If I have a procedure or a command in TCL, with variable number of arguments, one can use, if a list's elements are as an input, the "splatter" operator, for example:
set a [list "ko" ]
set m [ list "ok" "bang" ]
lappend a {*}$m
But, what if I want to "twice splatter"? I.e., flatten 2 levels? Using it twice, in sequence, does not work:
set a [list "ko" ]
set m [ list [ list "ok" ] [ list "bang" ] ]
lappend a {*}{*}$m
Will error out on extra character.
You've noticed that
{*}
(deliberately) doesn't go two steps deep.Your particular example isn't very indicative of the problem, so I suggest this:
Here, we get
a
set toko {{a b} {c d}} {{e f} {g h}}
. Which isn't what you wanted. But we can instead do this:Which gives this:
ko {a b} {c d} {e f} {g h}
. That looks right.But are we really doing the right thing here? Let's poke inside with our super-secret introspector, the
representation
command:Uh oh! We've lost the list-ness. It's not a catastrophe, but it isn't what we wanted. We instead should really do:
Well, that's more code but preserves list-ness (which would be good if you happened to have precious types on the leaves; core Tcl doesn't have such precious types, but some extensions do).
We can compare the timings:
Oh…
Hah! The type-correct one is better in a procedure(-like context).