Processes
A function that receives messages declares them with receives. That mailbox
is part of the function type and is invariant: a
fn() receives Integer -> :ok is not a fn() receives String -> :ok, and
Pid<Integer> is not a Pid<String>. receive is legal only inside a receiving
function, and its patterns must cover the mailbox. gale_std.process.self is
accepted only in a receiving function. The Pid message parameter must
match that mailbox.
mod processes
alias gale_std.process
pub type Message =| Ping(process.Pid<:pong>)| Stop
fn loop() receives Message -> :ok { receive { Ping(reply_to) -> { _ = process.send(reply_to, :pong) loop() } Stop -> :ok }}
pub fn start() -> process.Pid<Message> { process.spawn(fn() receives Message -> loop())}
pub fn round_trip(server: process.Pid<Message>) receives :pong -> :pong { reply_to = process.self() _ = process.send(server, Ping(reply_to)) receive { :pong -> :pong }}pub fn widen(pid: gale_std.process.Pid<Integer>) -> gale_std.process.Pid<Term> { pid}A receive pattern can pin a variable with ^name to match the value it
held when the receive started. In this example, {^tag, value} selects a reply
with the expected tag. The fallback {_, _} consumes replies with other tags
and waits again; it does not leave those replies in the mailbox.
mod processes
alias gale_std.process
pub type Tagged =| Ask(tag: process.Ref, reply_to: process.Pid<{process.Ref, Integer}>)| Halt
fn tagged_loop(n: Integer) receives Tagged -> :ok { receive { Ask(tag, reply_to) -> { _ = process.send(reply_to, {tag, n}) tagged_loop(n) } Halt -> :ok }}
fn await(tag: process.Ref) receives {process.Ref, Integer} -> Integer { receive { {^tag, value} -> value {_, _} -> await(tag) }}
pub fn tagged_round_trip() receives {process.Ref, Integer} -> Integer { server = process.spawn(fn() receives Tagged -> tagged_loop(7)) tag = process.make_ref() _ = process.send(server, Ask(tag, process.self())) value = await(tag) _ = process.send(server, Halt) value}gale_std.task wraps Elixir Task with an invariant handle. gale_std.ets
gives named tables a phantom identity so :users and :sessions handles
cannot be mixed. Both are stdlib, not extra syntax.