Structured Event-Driven Concurrency for Lua
[ About | Hello World! | Install & Run | Environments | Documentation | Resources ]
Atmos is a programming library for Lua that reconciles Structured Concurrency, Event-Driven Programming, and Functional Streams, extending classical structured programming with three main functionalities:
- Structured Deterministic Concurrency:
- A
taskprimitive with deterministic scheduling provides predictable behavior and safe abortion. - Structured primitives compose concurrent tasks with lexical scope (e.g.,
watching,every,par_or). - A
taskscontainer primitive holds attached tasks and control their lifecycle.
- A
- Event Signaling Mechanisms:
- An
awaitprimitive suspends a task and wait for events. - An
emitprimitive signals events and awake awaiting tasks.
- An
- Functional Streams (à la ReactiveX):
- Functional combinators for lazy (infinite) lists.
- Interoperability with tasks & events: tasks and events as streams, and streams as events.
- Safe finalization of stateful (task-based) streams.
Atmos is inspired by synchronous programming languages like Céu and Esterel.
During 5 seconds, displays Hello World! every second:
require "atmos.env.clock"
call(function ()
watching(clock{s=5}, function ()
every(clock{s=1}, function ()
print("Hello World!")
end)
end)
end)
We first the builtin clock environment, which provides timers to
applications.
The call primitive receives a function with the application logic in Atmos,
as follows:
- The
watchingcommand will execute its inner function during 5 seconds. - The
everyloop will execute its inner function every second. - Once the
watchingterminates, thecallreturns back to Lua.
Now, the same specification, but using streams:
require "atmos.env.clock"
local S = require "atmos.streams"
call(function ()
local s1 = S.from(clock{s=1})
:tap(function()
print("Hello World!")
end)
local s2 = S.from(clock{s=5}):take(1)
S.paror(s1,s2):to()
end)
s1is a periodic 1-second stream that prints the message on every occurrence, through thetapcombinator.s2is a periodic 5-seconds stream that terminates after its first occurrence, because oftake(1).S.parormerges the streams, terminating when either of them terminate.tois a sink that starts and exausts the full stream pipeline.
sudo luarocks install atmos --lua-version=5.4
lua5.4 <lua-path>/atmos/env/clock/exs/hello.lua
You may also clone the repository and copy part of the source tree, as follows,
into your Lua path (e.g., /usr/local/share/lua/5.4):
atmos
├── env/
│ ├── clock/
│ │ ├── exs/
│ │ │ ├── hello.lua
│ │ │ └── hello-rx.lua
│ │ └── init.lua
│ ├── iup/
│ │ ├── exs/
│ │ │ ├── button-counter.lua
│ │ └── init.lua
│ ├── sdl/
│ │ ├── exs/
│ │ │ ├── click-drag-cancel.lua
│ │ │ └── DejaVuSans.ttf
│ │ └── init.lua
│ └── socket/
│ ├── exs/
│ │ └── cli-srv.lua
│ └── init.lua
├── init.lua
├── run.lua
├── streams.lua
└── util.lua
Atmos depends on f-streams.
An environment is an external component that bridges input events from the real world into an Atmos application.
The standard distribution of Atmos provides the following environments:
atmos.env.clock: A simple pure-Lua environment that usesos.clockto issue timer events.atmos.env.socket: An environment that relies on luasocket to provide network communication.atmos.env.sdl: An environment that relies on lua-sdl2 to provide window, mouse, key, and timer events.atmos.env.iup: An environment that relies on IUP (iup-lua) to provide graphical user interfaces (GUIs).
- A toy problem: Drag, Click, or Cancel
- A simple but complete 2D game in Atmos:
- Academic publications (Céu):
- Mailing list (Céu & Atmos):
