Symbols
EventFlow uses a minimal set of symbols to distinguish between different elements. This creates a visual language that's easy to scan and understand.
Symbol Overview
| Element | Symbol | Position | Example |
|---|---|---|---|
| Guard | ? | line prefix | ? cart is valid |
| Guard (OR) | ?? | line prefix | ?? user is admin |
| Assertion | = | line prefix | = order is in #processing |
| API Event | > | before on | on> :checkout from @customer |
| Actor | @ | inline | @customer |
| Event | : | inline | :checkout |
| State | # | inline | #processing |
| Context | $ | inline | $total |
Line Prefixes vs Inline Symbols
Line Prefixes
Line prefixes indicate what the line does:
| Prefix | Meaning | Example |
|---|---|---|
| (none) | Action (default) | order moves to #paid |
? | Guard (condition) | ? cart is not empty |
?? | OR guard | ?? user is admin |
= | Assertion | = order is in #paid |
Actions are the default - no prefix needed:
on> :checkout from @customer
order moves to #awaiting_payment // action (no prefix)
emit :payment_request to @payment // action (no prefix)Inline Symbols
Inline symbols indicate references within a line:
emit :payment_request to @payment
// ↑ ↑
// event symbol actor symbolorder moves to #awaiting_payment
// ↑
// state symbol$total increases by $item.price
// ↑ ↑
// context symbolsActor Symbol: @
The @ symbol identifies actors (machines) in the system:
machine: @order // Define an actor
on> :checkout from @customer // Event from an actor
emit :request to @payment // Send to an actorActors are:
- State machine instances
- Event senders and receivers
- Isolated units with their own context
Event Symbol: :
The : symbol identifies events:
on> :checkout from @customer // Receive an event
emit :payment_request to @payment // Send an event
on :payment_success from @payment // Internal eventEvents are:
- Named messages between actors
- Triggers for state transitions
- The only way actors communicate
State Symbol:
The # symbol identifies states:
order moves to #awaiting_payment
order moves to #paid
order moves to #shipped
? order is in #processingStates are:
- Named conditions of a machine
- Automatically inferred from usage
- No upfront declaration needed
Context Symbol: $
The $ symbol identifies context variables:
$total becomes 100
$items adds "Laptop"
$customer_id becomes "C-001"
? $total > 0
process paymentContext variables are:
- Data owned by a machine instance
- Automatically inferred from usage
- Can have optional type annotations
Type Annotations
$total: number becomes 100
$items: array adds "Laptop"
$customer_id: string becomes "C-001"
$is_premium: boolean becomes trueSupported types: string, number, boolean, array, object
Guard Symbol: ?
The ? symbol marks a condition line:
on> :checkout from @customer
? cart is not empty // Guard
order moves to #awaiting_paymentMultiple Guards (AND)
Multiple ? lines are combined with AND:
? cart is valid
? payment is authorized
? inventory is available
process the order // Only runs if ALL passOR Guards
Use ?? for OR conditions:
? user is admin
?? user has override permission
skip validation // Runs if either passesComplex Combinations
? condition a
? condition b
?? condition c
?? condition d
do somethingReads as: (a AND b) OR c OR d
Default Case (otherwise)
When no guards pass, use otherwise:
on> :process_refund from @customer
? days since purchase < 7
full refund
order moves to #refunded
? days since purchase < 30
partial refund (50%)
order moves to #partially_refunded
otherwise
refund denied
emit :refund_rejected to @customerYou can also use an empty ?:
? days < 7
full refund
? days < 30
partial refund
?
refund deniedAssertion Symbol: =
The = symbol marks an assertion line:
expect:
= order is in #paid
= $total equals 1200
= @customer received :confirmationAssertions are used in expect: blocks and verify that conditions are true after events execute.
API Event Symbol: >
The > symbol before on indicates a public/API endpoint:
on> :checkout from @customer // External API - can be called directly
order moves to #awaiting_payment
on :payment_success from @payment // Internal - only from other machines
order moves to #paidThe > prefix means:
- This event can be triggered externally (via API)
- It's the entry point for external systems
- It does NOT determine whether a new aggregate is created
Symbol Summary Table
| Symbol | Name | Where Used | Purpose |
|---|---|---|---|
@ | Actor | Inline | Reference to a machine |
: | Event | Inline | Reference to an event |
# | State | Inline | Reference to a state |
$ | Context | Inline | Reference to a variable |
? | Guard | Line prefix | Condition check |
?? | OR Guard | Line prefix | OR condition |
= | Assertion | Line prefix | Test verification |
> | API | Before on | Public endpoint |
Lowercase Convention
Everything is lowercase except string literals:
machine: @order // lowercase
scenario: add to cart // lowercase
on :add_item from @customer // lowercase
$items adds "Laptop" // string literal: as-is
order moves to #checkout // lowercase