Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
ego_script [2026/08/18 02:37]
hermann
ego_script [2026/08/31 15:12] (current)
hermann
Line 223: Line 223:
 </​code>​ </​code>​
  
-Any output can be replaced with ''​_'' ​to discard ​it when only some outputs are needed.+When only some of a functor'​s outputs are wanted, the rest can simply be left out of the block entirely — nominal syntax binds by name, so there'​s no position to hold open the way [[#​positional_syntax|positional syntax]] requires. An unwanted ​output can also be bound to ''​_'' ​instead of omitted; this changes nothing about execution, ​it only makes explicit, at the call site, that the output was considered and deliberately discarded rather than overlooked.
  
 So inputs read ''​portName = value''​ while outputs read ''​variable = portName''​. The two directions are summarized below: So inputs read ''​portName = value''​ while outputs read ''​variable = portName''​. The two directions are summarized below:
Line 290: Line 290:
   * **Loops.** Several containers repeat their contents. [[Repeat]] runs them a fixed number of times; [[For]] iterates over a numeric range; [[For Each]] iterates over the rows of a table; [[For Each Category]] iterates over the categories of a map; [[For Each Region]] iterates over the regions of a map; and [[While]] and [[Do While]] repeat for as long as a condition holds.   * **Loops.** Several containers repeat their contents. [[Repeat]] runs them a fixed number of times; [[For]] iterates over a numeric range; [[For Each]] iterates over the rows of a table; [[For Each Category]] iterates over the categories of a map; [[For Each Region]] iterates over the regions of a map; and [[While]] and [[Do While]] repeat for as long as a condition holds.
   * **Region management.** [[Region Manager]] establishes a region context and runs its contents once for that context, exposing the region to the functors inside it.   * **Region management.** [[Region Manager]] establishes a region context and runs its contents once for that context, exposing the region to the functors inside it.
-  * **Error handling.** [[Skip On Error]] and [[Skip All On Error]] execute their contained functors while capturing and ignoring any error that occurs. Both accept a ''​trapAndIgnoreErrors''​ boolean input — when set to false, they behave as a plain ''​Group''​ and errors are not suppressed. Both also produce an ''​executionCompletedSucessfully''​ output that can be tested by subsequent functors. The two differ in what happens to results already produced when an error is raised: [[Skip On Error]] preserves the outputs of any functors that completed successfully before the error; [[Skip All On Error]] discards all of them. They are typically paired with a junction outside the container to react to the outcome — see [[#​error-handling_pattern|Error-handling pattern]] below.+  * **Error handling.** [[Skip On Error]] and [[Skip All On Error]] execute their contained functors while capturing and ignoring any error that occurs. Both accept a ''​trapAndIgnoreErrors''​ boolean input — when set to false, they behave as a plain ''​Group''​ and errors are not suppressed. Both also produce an ''​executionCompletedSuccessfully''​ output that can be tested by subsequent functors. The two differ in what happens to results already produced when an error is raised: [[Skip On Error]] preserves the outputs of any functors that completed successfully before the error; [[Skip All On Error]] discards all of them. They are typically paired with a junction outside the container to react to the outcome — see [[#​error-handling_pattern|Error-handling pattern]] below.
  
 The [[#​calculator_functor_shorthand|calculator functors]] described later in this section are also containers: each holds the expression it evaluates, and in its verbose form holds a block of operand definitions. The [[#​calculator_functor_shorthand|calculator functors]] described later in this section are also containers: each holds the expression it evaluates, and in its verbose form holds a block of operand definitions.
Line 354: Line 354:
 </​code>​ </​code>​
  
-> **Note:** Sequence ports are only needed when two containers have no natural data dependency between them — if one container already produces a value that the other consumes, the ordering is already established and no sequencing port is required. Before sequence ports were available, models used a **forced-dependency pattern** — creating a dummy data value inside one container and consuming it inside another to manufacture an artificial data dependency. This idiom still appears in older scripts but is now a last resort, used only for functors that do not expose ''​sequenceInput''​ and ''​sequenceOutput''​ ports (such as [[Skip On Error]] and [[Skip All On Error]], which instead expose an ''​executionCompletedSucessfully''​ boolean output that can serve the same purpose).+> **Note:** Sequence ports are only needed when two containers have no natural data dependency between them — if one container already produces a value that the other consumes, the ordering is already established and no sequencing port is required. Before sequence ports were available, models used a **forced-dependency pattern** — creating a dummy data value inside one container and consuming it inside another to manufacture an artificial data dependency. This idiom still appears in older scripts but is now a last resort, used only for functors that do not expose ''​sequenceInput''​ and ''​sequenceOutput''​ ports (such as [[Skip On Error]] and [[Skip All On Error]], which instead expose an ''​executionCompletedSuccessfully''​ boolean output that can serve the same purpose).
  
 ==== Internal output ports ==== ==== Internal output ports ====
Line 502: Line 502:
 </​code>​ </​code>​
  
-When only a pass/fail signal is needed — not an actual fallback value — a junction is unnecessary:​ [[Skip All On Error]] already reports success or failure directly through its own ''​executionCompletedSucessfully''​ output, with no sentinel or junction required:+When only a pass/fail signal is needed — not an actual fallback value — a junction is unnecessary:​ [[Skip All On Error]] already reports success or failure directly through its own ''​executionCompletedSuccessfully''​ output, with no sentinel or junction required:
  
 <​code>​ <​code>​
Line 514: Line 514:
 [[Skip On Error]] behaves differently:​ instead of discarding all results, it preserves the outputs of any functors that had already completed when the error was raised. Substituting it into the paired-loading example above would be a mistake: since ''​loadedMap''​ and ''​loadedWeights''​ have no data dependency on each other — see [[#​functors_variables_and_binding|Functors,​ variables, and binding]] for that execution-order rule stated generally — nothing guarantees which of the two, if either, has already completed by the time the other'​s error is raised. The outcome would be a race: a real map could end up paired with default weights, or the reverse, unpredictably from run to run. [[Skip All On Error]] sidesteps that race entirely — it discards both regardless of which one failed or how far the other had gotten — which is exactly what "​succeed together or not at all" requires. [[Skip On Error]] instead earns its place when partial results are genuinely fine to keep on their own — see below. [[Skip On Error]] behaves differently:​ instead of discarding all results, it preserves the outputs of any functors that had already completed when the error was raised. Substituting it into the paired-loading example above would be a mistake: since ''​loadedMap''​ and ''​loadedWeights''​ have no data dependency on each other — see [[#​functors_variables_and_binding|Functors,​ variables, and binding]] for that execution-order rule stated generally — nothing guarantees which of the two, if either, has already completed by the time the other'​s error is raised. The outcome would be a race: a real map could end up paired with default weights, or the reverse, unpredictably from run to run. [[Skip All On Error]] sidesteps that race entirely — it discards both regardless of which one failed or how far the other had gotten — which is exactly what "​succeed together or not at all" requires. [[Skip On Error]] instead earns its place when partial results are genuinely fine to keep on their own — see below.
  
-Whatever [[Skip On Error]] preserves is what each branch has to work with. If the branches only need to pick between two values — the case in the [[manipulating_tables_and_lookup_tables#​printing_a_table_with_a_generic_format|generic printer]] above — a junction is the simplest tool. But when the branches need to carry out different logic rather than just hand a value onward, [[If Then]]/[[If Not Then]] can test [[Skip On Error]]'​s own ''​executionCompletedSucessfully''​ output directly — no separate sentinel needed, unlike the paired-loading [[Skip All On Error]] pattern above. This example attempts to load an optional mask map; if it loads, the matching branch has the mask itself to work with, and if it's missing or fails to load, the other branch proceeds without one:+Whatever [[Skip On Error]] preserves is what each branch has to work with. If the branches only need to pick between two values — the case in the [[manipulating_tables_and_lookup_tables#​printing_a_table_with_a_generic_format|generic printer]] above — a junction is the simplest tool. But when the branches need to carry out different logic rather than just hand a value onward, [[If Then]]/[[If Not Then]] can test [[Skip On Error]]'​s own ''​executionCompletedSuccessfully''​ output directly — no separate sentinel needed, unlike the paired-loading [[Skip All On Error]] pattern above. This example attempts to load an optional mask map; if it loads, the matching branch has the mask itself to work with, and if it's missing or fails to load, the other branch proceeds without one:
  
 <​code>​ <​code>​
Line 1116: Line 1116:
 | **Use abbreviated syntax for Calculate family functors** | Whether the ''​Calculate''​ family is written using the shorthand symbol (''#'',​ ''##'',​ ''​%'',​ etc.) or the full functor name. See the [[#​calculator_functor_shorthand|Calculator functor shorthand]] section for details. | | **Use abbreviated syntax for Calculate family functors** | Whether the ''​Calculate''​ family is written using the shorthand symbol (''#'',​ ''##'',​ ''​%'',​ etc.) or the full functor name. See the [[#​calculator_functor_shorthand|Calculator functor shorthand]] section for details. |
 | **Preferred number of columns before wrapping comments** | The line width at which the generator wraps long comment text. | | **Preferred number of columns before wrapping comments** | The line width at which the generator wraps long comment text. |
-