A Wrapper is a Shell that limits the scope of events — the Simorg equivalent of a scope in classical languages. Events exist only inside the Shell that wraps them.
Use curly braces <<<{}>>> to create a wrapper. Simorg provides three kinds:
| Wrapper | Behavior |
|---|---|
| Isolator | Closed space — events cannot exit |
| Conditional | Activated by an external event |
| IO | Bidirectional — events flow in and out |
Isolator
An isolator is a closed Shell. Events inside it cannot leave. Outer variables remain readable unless shadowed by a local declaration.
"Outside the Shell" $myVariable
myVariable ?
{
"Inside the shell" $myVariable
myVariable ?
}
// Outside the Shell
// Inside the shell
Reuse an outer variable when it is not redeclared inside:
"Outside the Shell" $myVariable
{
myVariable ?
}
An isolator is active when its parent is active. Nothing outside can access its internal elements.
Conditional
A conditional is an isolator with an explicit activator — an event that opens the Shell so internals can run.
1 {
"Hello World!" ?
}
Any expression can activate a Shell: variables, calculations, gates, pipelines. A classic if-style pattern uses an AND gate:
100 $a
200 $b
(a > 50, b > 50) {
"'a' and 'b' are greater than 50" ?
}
There is no <<<else>>>. Pathways must be explicit — use <<<&>>> and <<<!&>>> (or separate conditions) so every branch is a real channel for data.
You can declare a variable as part of a wrapper statement — either to receive external data, or to give the Shell a name and dedicated space:
$externalData {
externalData ?
}
"External Event" externalData
$myVar {
"Dedicated space for complex suffix logic" ?
}
"External Event" myVar
The activator is a hole: external events pass through it into the Shell. Prefer a plain eventflow when the side effect is a single action — wrappers shine when you need a real space.
Layer Operator
The layer operator <<<.>>> walks through nested identity layers to reach a specific field — similar to member access in classical languages, but driven by Shell layers.
(
"Hello!" $hello,
"Bye!" $bye
) $message
message.hello ?
Push into a named slot:
(
$hello,
$bye
) $message
"Hello" message.hello
"Bye" message.bye
message ?
// (hello: Hello, bye: Bye)
Or structure and destructure in one step:
(
$hello,
$bye
) $message
("Hello", "Bye") message
message ?
Named gate slots behave like object fields. Destructuring into an AND gate requires matching length; an OR gate accepts whatever is available. A length mismatch on AND logs <<<INVALID_DESTRUCTION_PATTERN>>> and discards the event.
IO
An IO wrapper uses the same <<<{}>>> syntax as a conditional. The difference is setup: data flows in from outside and out from inside — bidirectional event flow.
A simple adder:
$sum {
($a, $b) $args
sum args
args.a + args.b sum
}
(10, 20) sum ? // 30
- Declare the argument shape with an AND gate.
- Destructure the incoming event into <<<args>>>.
- Push the result back into <<<sum>>> — the Shell knows this is an internal event, so it does not re-activate.
IO looks like a function on the surface, but it is a data-driven mathematical structure — no program counter, no return address.
For multiple inputs and outputs, declare them in the activator with an OR gate:
[$arg1, $arg2, $add, $sub, $mul, $div] $calculate {
calculate.arg1 + calculate.arg2 calculate.add
calculate.arg1 - calculate.arg2 calculate.sub
calculate.arg1 * calculate.arg2 calculate.mul
calculate.arg1 / calculate.arg2 calculate.div
}
(10, 5) calculate ?
// [add: 15, sub: 5, mul: 50, div: 2]
When a declaration owns its wrapper, only events that originate inside the Shell become the identifier's value. Using that identifier as a pipeline head receives those internal results — not the raw input arguments.
Conclusion
Wrappers are spaces. Isolators close them; conditionals open them with an activator; IO shells make the flow bidirectional.
Combine wrappers with gates and eventflows for rich patterns — but do not force classical OOP shapes onto Simorg. Prefer pathways that event can follow naturally.