Handlers
Handlers are special functions that are triggered by events emitted to the event loop. They are the root of all stacks in Alan. Like many languages with event loops, multiple handlers can exist for a single event.
Event handler functions must always have a void
return. From the perspective of the language, handlers are self-contained side-effects.
Handlers can only be registered at the module level, not within a function. This is both to discourage abuse of the event loop and make a more intelligent execution planning possible in the future (such as switching from minimizing total latency for any given event to maximizing the total throughput of event processing if the event loop queue is backing up).
Furthermore, function calls within the handler run may trigger multiple simultaneous executions and IO operations can break up the handler call into multiple fragments to be re-scheduled onto the event loop. The vast majority of the time, direct control on how work is scheduled onto the event loop is abstracted from the developer.
The event handler syntax is relatively simple:
on eventName function
where eventName
is the name of the event to register a handler for and function
is either the name of a function, or an in-line defined function, eg:
on event fn namedHandler(argument: eventType) {
...
}
for a fully-named in-line defined function with an event payload. Without a payload, the argument list can be dropped:
on event fn namedHandler {
...
}
In both cases, the name is also optional because it is being registered immediately:
on event fn (argument: eventType) {
...
}
or
on event fn {
...
}
The latter purely-side-effect-only function can also omit the fn
if desired as it is unambiguous in this context:
on event {
...
}
Special Events: @std/app.start, @std/app.exit, and @std/app.stdout
There are events that are particularly special for Alan. The start
, exit
, and stdout
events in the @std/app
standard library module. They are separated from the built-ins because most modules should not need to ever touch them, but the root module of your project may.
When Alan has finished loading your code and has the event loop set up, it emits a single start
event (of type void
). That should trigger a special function used to set up the rest of your program: loading configuration, starting up an http server, or what have you.
Once the event loop is running, it will run forever. Only if an int8
value (the exit code, where 0 is successful and anything else is an error) is emitted to the exit
event will the process tear itself down and terminate.
If you want to write raw text to stdout
you can emit
to a string to it (this is what the print
function does, but with an appended newline character after converting your argument to a string).
This is why basically all of the small examples import these events from @std/app
, but most modules in most larger projects never will.