Actor
The Actor module provides lightweight concurrent actors for message-based programming. Actors are independent entities with their own state that communicate via asynchronous message passing, inspired by Erlang and Pony.
Actor creation and actor registry operations require ActorAuth,
ConcurrencyAuth, or RootAuth in scope.
Each actor has a mailbox for incoming messages, internal state, and a handler function.
Messages are processed cooperatively via Actor.tick or automatically in threaded mode.
Creating Actors
# Define a counter handler
handler = fn(msg, state) =>
match msg
| 1 -> state + 1
| -1 -> state - 1
| _ -> state
# Create the actor with initial state 0
counter = Actor.new handler 0
println "Created actor: ${counter}"
Message Passing
# Send messages using Actor.send
Actor.send counter 1 # increment
Actor.send counter 1 # increment
Actor.send counter -1 # decrement
# Or use the <- operator
counter <- 1
counter <- :reset
# Process all messages
processed = Actor.tick counter
println "Processed ${processed} messages"
Some value if available, None if empty.
Lifecycle
# Graceful shutdown
Actor.stop counter
Actor.stop for graceful shutdown.
State Access
current = Actor.state counter
println "Counter value: ${current}"
Actor Registry
Actors can be registered with names for easy lookup across the application.
Actor.register "my-counter" counter
Some actor-id if found, None otherwise.
match Actor.lookup "my-counter"
| Some id -> id <- 1
| None -> println "Actor not found"
Error Types
Actor operations that may fail use the ActorError type.
type ActorError =
| SpawnError { message: String }
| SendError { message: String }
| ReceiveError { message: String }
| ActorNotFound
| ActorStopped
| RegistryError { message: String }
| ActorError { message: String }
Complete Example
# A simple counter actor
handler = fn(msg, state) =>
match msg
| :inc -> state + 1
| :dec -> state - 1
| :reset -> 0
| _ -> state
# Create and register the actor
counter = Actor.new handler 0
Actor.register "counter" counter
# Send messages using <- operator
counter <- :inc
counter <- :inc
counter <- :dec
# Process all messages
Actor.tick counter
# Check the result
println "Final count: ${Actor.state counter}" # => 1
# Cleanup
Actor.stop counter