Skip to content

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

ElementSymbolPositionExample
Guard?line prefix? cart is valid
Guard (OR)??line prefix?? user is admin
Assertion=line prefix= order is in #processing
API Event>before onon> :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:

PrefixMeaningExample
(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:

flow
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:

flow
emit :payment_request to @payment
//    ↑                   ↑
//    event symbol        actor symbol
flow
order moves to #awaiting_payment
//             ↑
//             state symbol
flow
$total increases by $item.price
// ↑                ↑
// context symbols

Actor Symbol: @

The @ symbol identifies actors (machines) in the system:

flow
machine: @order              // Define an actor

on> :checkout from @customer // Event from an actor
  emit :request to @payment  // Send to an actor

Actors are:

  • State machine instances
  • Event senders and receivers
  • Isolated units with their own context

Event Symbol: :

The : symbol identifies events:

flow
on> :checkout from @customer  // Receive an event
  emit :payment_request to @payment  // Send an event

on :payment_success from @payment  // Internal event

Events are:

  • Named messages between actors
  • Triggers for state transitions
  • The only way actors communicate

State Symbol:

The # symbol identifies states:

flow
order moves to #awaiting_payment
order moves to #paid
order moves to #shipped

? order is in #processing

States are:

  • Named conditions of a machine
  • Automatically inferred from usage
  • No upfront declaration needed

Context Symbol: $

The $ symbol identifies context variables:

flow
$total becomes 100
$items adds "Laptop"
$customer_id becomes "C-001"

? $total > 0
  process payment

Context variables are:

  • Data owned by a machine instance
  • Automatically inferred from usage
  • Can have optional type annotations

Type Annotations

flow
$total: number becomes 100
$items: array adds "Laptop"
$customer_id: string becomes "C-001"
$is_premium: boolean becomes true

Supported types: string, number, boolean, array, object

Guard Symbol: ?

The ? symbol marks a condition line:

flow
on> :checkout from @customer
  ? cart is not empty        // Guard
    order moves to #awaiting_payment

Multiple Guards (AND)

Multiple ? lines are combined with AND:

flow
? cart is valid
? payment is authorized
? inventory is available
  process the order         // Only runs if ALL pass

OR Guards

Use ?? for OR conditions:

flow
? user is admin
?? user has override permission
  skip validation           // Runs if either passes

Complex Combinations

flow
? condition a
? condition b
?? condition c
?? condition d
  do something

Reads as: (a AND b) OR c OR d

Default Case (otherwise)

When no guards pass, use otherwise:

flow
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 @customer

You can also use an empty ?:

flow
? days < 7
  full refund
? days < 30
  partial refund
?
  refund denied

Assertion Symbol: =

The = symbol marks an assertion line:

flow
expect:
  = order is in #paid
  = $total equals 1200
  = @customer received :confirmation

Assertions 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:

flow
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 #paid

The > 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

SymbolNameWhere UsedPurpose
@ActorInlineReference to a machine
:EventInlineReference to an event
#StateInlineReference to a state
$ContextInlineReference to a variable
?GuardLine prefixCondition check
??OR GuardLine prefixOR condition
=AssertionLine prefixTest verification
>APIBefore onPublic endpoint

Lowercase Convention

Everything is lowercase except string literals:

flow
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

Released under the MIT License.