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
manipulating_tables_and_lookup_tables [2026/07/25 04:12]
hermann
manipulating_tables_and_lookup_tables [2026/07/25 04:29] (current)
hermann
Line 302: Line 302:
 A [[Mux Table]] or [[Mux Lookup Table]] can carry a Table or Lookup Table across the iterations of a loop, the same way [[Mux Value]] carries a single value — see [[ego_script#​carrying_and_selecting_values_across_iterations|Carrying and selecting values across iterations]]. Each iteration reads the mux's current output, adds a row to it with ''​AddTableRow'',​ and feeds the result back in as the mux's ''​feedback''​ input for the next iteration, building up a result table one row at a time. A [[Mux Table]] or [[Mux Lookup Table]] can carry a Table or Lookup Table across the iterations of a loop, the same way [[Mux Value]] carries a single value — see [[ego_script#​carrying_and_selecting_values_across_iterations|Carrying and selecting values across iterations]]. Each iteration reads the mux's current output, adds a row to it with ''​AddTableRow'',​ and feeds the result back in as the mux's ''​feedback''​ input for the next iteration, building up a result table one row at a time.
  
-Neither [[For Each]] nor [[While]]/​[[Do While]] has a data output of its own — each only has a sequencing output, per its own entry in the functor catalog. So there'​s no dedicated port to "​collect"​ the final accumulated table once the loop ends. Instead, ​a functor ​placed outside ​the loop simply ​references ​the accumulator'​s feedback variable ​directlythe same way any functor can reference a variable produced inside a container; ​per [[basic_data_flow|Basic Data Flow]], that reference is itself a dependency on the whole loop, so Dinamica waits for every iteration to finish before evaluating it.+The accumulated table is read after the loop the same way any container'​s internal result is read from outside it: a functor ​after the loop simply ​takes the accumulator'​s feedback variable ​as an input. There'​s nothing special about this — the loop is guaranteed to finish before anything depending on it runs, per [[basic_data_flow|Basic Data Flow]].
  
 <​code>​ <​code>​
Line 327: Line 327:
 }}; }};
  
-// finalResults holds every row added across ​every iterationnot just the +// finalResults holds every row added across ​all iterations. Use nextAccumulated
-// last one — accumulated (the mux's own output) ​would lag one iteration behind. +// not accumulated (the mux's own output), which lags one iteration behind. 
-// A bare `finalResults := nextAccumulated;​` isn't valid — := always binds the +// The Table carrier passes it through, since := always binds a functor call.
-// result of a functor call, never just another variable'​s name — so the Table +
-// carrier functor is used here to re-expose the value under a new binding.+
 finalResults := Table nextAccumulated;​ finalResults := Table nextAccumulated;​
 </​code>​ </​code>​
 +
 +> **Note:** This is also why ''​accumulated''​ should never be read again after ''​AddTableRow''​ consumes it in the same iteration. When exactly one reference to a table'​s current version remains, Dinamica can update it destructively — modifying the existing storage in place. A second live reference to ''​accumulated''​ (reading it directly somewhere else, instead of only through ''​nextAccumulated''​) forces Dinamica to copy the table instead, since the old version now has to stay intact for that other reference. That copy cost repeats every iteration — see [[basic_data_flow|Basic Data Flow]] for this same rule stated generally, beyond just tables.
  
 **Why this isn't the best approach.** [[basic_data_flow|Basic Data Flow]] documents three conditions under which a loop's iterations can run simultaneously:​ no mux directly inside the loop, nothing produced inside the loop consumed outside it, and no loop member used as a submodel'​s output port. A mux-based accumulator like the one above breaks the first condition outright — the mux ties every iteration to the one before it, so the loop can never run as anything but sequential, even when the per-iteration work is otherwise completely independent,​ as it is above (each row's value depends only on that row's own key). **Why this isn't the best approach.** [[basic_data_flow|Basic Data Flow]] documents three conditions under which a loop's iterations can run simultaneously:​ no mux directly inside the loop, nothing produced inside the loop consumed outside it, and no loop member used as a submodel'​s output port. A mux-based accumulator like the one above breaks the first condition outright — the mux ties every iteration to the one before it, so the loop can never run as anything but sequential, even when the per-iteration work is otherwise completely independent,​ as it is above (each row's value depends only on that row's own key).