System::Async
Asynchrony in Orchid is realised via a central event loop that is available for all systems. As such, the tools used to control asynchrony are universal.
yield cmd
A standalone command. When returned as the value of a program, instructs the event queue to wait for the next event.
export const print := \text. \ok. (
io::write_str io::stdout text
(io::flush io::stdout
ok
(\e. panic "println threw on flush")
\_. yield
)
(\e. panic "print threw on write")
\_. yield
)
Orchid's IO is actually completely asynchronous; write_str
and flush
both take three callbacks, success, failure, and the sync next step. Since print
blocks until the text is on the screen, after each of these commands we place the continuation in success and yield
as the sync next step. If we wanted to do more work while our text gets printed, we could've used write_str
directly and put the rest of the operation in its sync next step.
set_timer bool -> number -> cmd -> (cmd -> cmd) -> cmd
Sets a timer. Parameters specify whether the timer is recurring, the delay in seconds, the command to be executed when the timer fires, and the sync next step. The sync next step receives a canceller which is itself a command. If this command is called, later iterations of the timer will not run.
import system::async::(set_timer, yield)
import system::io::(readln, println)
import std::exit_status
const main := do{
cps cancel = set_timer true 1 (println "y" yield);
cps _ = readln;
cps cancel;
exit_status::success
}