Event Flow

Source: reference-book. Raw markdown: /raw/docs/reference-book/Event-Flow.md

These operators are the glue between Shells. They create pathways in which events stream from left to right, forming a pipe.

A pipe shapes when operators chain together. A pipe does not release events outside itself unless you explicitly route them out using variables.

These operators are quite intoivite and easy to remember.

Opener

Use <<<:>>> to make a pipe dependent to future events.

When a pipe doesn't have a head operator, it is called Closed. the leading value self-triggers at startup:

200 $myConst200

Use <<<:>>> as head operator to open up the pipe to future events. Open pipe is dependent to an exteranal event:

:200 $myConst200 ? // nothing logged

Push data into another pipe through a variable:

// passing event into myConst200 and receiving event back
100 myConst200 ? 

Combine both behaviors with a gate, auto-init at startup and accept events later:

// notice how : is used as a gate slot
// this way we receive incoming event into a slot
:[ 200, :] $myConst200

100 myConst200
myConst200 ? // 200
             // 100

Arithmetic

Binary operators consume their right-hand operand: <<<+>>>, <<<->>>, <<<*>>>, <<</>>>, <<<%>>>.

19 $numA
 2 $numB

numA + numB $add
add ? // 21

<<<++>>> and <<<-->>> are Unary operators and they do not need an operand.

19++ ? // 20

<<<+>>> can be used also to join string or buffers.

strA + strB $strC       // Hello World!
strC + 100 + 20 $strD   // Hello World!10020

No operator precedence, evaluation is strictly left to right:

1 + 2 * 5 / 15 ? // 1

Parentheses in calculations create a gate, not grouping.

When using <<<->>> as a subtraction operator, do not forget to put a space after it, otherwise it will be considered a negative sign for the next token.

Relational

Relational operators do not return booleans. On success, the subject (left side) passes through unchanged. The object (right side) is what it is checked against.

20 = 20 $x
x ? // 20

20 = 10 $y
y ? // never releases
OperatorMeaning
<<<=>>>equal
<<<!>>>not equal
$$$KeywordSnippet keyword=> $$$ <<<>=>>>greater / greater-or-equal
$$$KeywordSnippet keyword=< $$$ <<<<=>>>less / less-or-equal

Empty values of different types are not equal (<<<0x>>> ≠ <<<"">>>). Type coercion is automatically happening between numbers and strings so <<<"1">>> is equal to <<<1>>>.

Please note, <<<=>>> is equality check and simorg doesn't have classical assignment operator anymore as the whole system is naturally communicating using events.

Subject drives execution — with XOR gates, which operand is the subject changes what gets logged:

[1;2;3] $x
2 $y

x > y ? // logs only 3
y > x ? // logs only 2

Truthy

Unary operator <<<&>>> passes the event through only if the value is truthy.

Truthy: any non-zero number, non-empty string, non-empty buffer.

1 & "will pass" ?
0 & "will never release" ?

For gates: AND is truthy when all slots are truthy; OR when at least one is.

Not truthy <<<!&>>> is the inverse. Use both branches explicitly instead of a classical <<<else>>>:

"" $userInput
userInput &
userInput !& "Invalid Empty Value Received!" ?

Declaration

<<<$>>> marks the next token as a variable identifier. Definition happens at runtime when data arrives.

Prefix: expressions before <<<$>>> are part of the variable's essence:

% 3 $var
100 var ? // 1

Suffix: expressions after the identifier run as a side effect when the variable releases:

($x, $y, 0 $z) $point

1 point.x
2 point.y

point.x ? // 1
point ?   // (x: 1, y: 2, z: 0)

Prefix shapes what the variable holds; suffix shapes what happens when it releases.

Logger

<<<?>>> logs the value and passes it through (newline appended).

"Hello World!" ?

<<<??>>> logs without a trailing newline. Useful for streaming output.

Do Not Care

<<<|>>> skips the data and keeps only the act of the event. Useful for syncing without carrying values.

$x

(x, 1, 2) ? // (Trigger, 1, 2)
(x |, 20, 30) ? // (20, 30)

"Trigger" x

Gates exclude Do Not Care slots from their output. Use as a signal beacon:

| $trigger

100 trigger
"Start" trigger

Do Not Care events do not appear in logs.

Filter

<<<@>>> passes an event only if it carries a specific frequency (identity layer). Still evolving.

$x
$y

(10 x, 20 y) $pointA

pointA @x ? // 10

Collector

<<<..>>> batches streaming events into a collection <<<{ }>>> — Simorg's answer to arrays, without index-based access.

:[0, :] $data <10 ++data

data ..10 ?
// {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

Chain collectors to batch then release one by one:

data ..10..2 ?

Design size-dependent logic while the collector fills — not after. Data should stream naturally; collectors are temporary holding points, not storage.

Include

<<<#>>> brings in external resources inside runtime.

Artifacts

Passing artifact identifier like,

"@simorg/delay0.1.0" #delay
"Waiting for 3 Seconds..." ? 3 delay.sec "Done!" ?

Local files

To include another source file inside current file,

"../my-artifact/main.art" #localArtifact

Agentic Runtime

Code will be generated by runtime manager,

First include a runtime manager, for example,

"@runtime/runtime-manager0.1.0" #openAi

Now you can send prompts!

In an agentic runtime a standalone String value is considered an anonymous prompt,

// a standalone string value
"Create a web application on port 3000 with an empty layout" #appLayout

// not a prompt as it is used in a pipe
"Hello World!" ?

You can name your prompt and use the result later,

// this creates an artifact named chatComponent
"Create an agentic chatComponet, place it inside appLayout" #chatComponent

chatComponent.userPrompt ?

If you need to use an anonymous conditional prompt, simply use <<<#>>> without an identifier,

// this is a conditional prompt
chatComponent.onClose "Exit this application" #

Please join our pilot program to access Agentic Runtime feature.

Conclusion

Binary — needs a right-hand operand:

CategoryOperators
Arithmetic<<<+>>> <<<->>> <<<*>>> <<</>>> <<<%>>>
Relational<<<=>>> <<<!>>> $$$KeywordSnippet keyword=> $$$ $$$KeywordSnippet keyword=>= $$$ $$$KeywordSnippet keyword=< $$$ $$$KeywordSnippet keyword=<= $$$
Variable<<<$>>>
Collector<<<..>>>
Filter<<<@>>>

Optional - using operand is optional

CategoryOperators
Include<<<#>>>

Unary — no operand needed:

CategoryOperators
Opener<<<:>>>
Truthy<<<&>>> <<<!&>>>
Logger<<<?>>> <<<??>>>
Do Not Care<<<|>>>
Arithmetics<<<++>>> <<<-->>>