Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>One option would be creating specialized procs on the fly:</p> <p>Not sure how fast it is for larger N or larger sets, but should be quite fast for repeated runs, as you have nearly no overhead than straight calls to <code>foreach</code> and <code>lappend</code>.</p> <pre><code>package require Tcl 8.4 # stuff subcommands in a namespace namespace eval ::unlzip {} proc unlzip {L n} { # check if we have the proc already set name [format "::unlzip::arity%dunlzip" $n] if {[llength [info commands $name]]} { return [$name $L] } else { # create it proc $name {V} [::unlzip::createBody $n] return [$name $L] } } proc ::unlzip::createBody {n} { for {set i 0} {$i &lt; $n} {incr i} { lappend names v$i lappend lnames lv$i } set lbody "" set ret { return [list } foreach lname $lnames name $names { append lbody [format { lappend %s $%s} $lname $name] append ret "\$$lname " } append ret {]} return [format {foreach {%s} $V { %s } %s} $names $lbody $ret] } proc ::unlzip::arity1unlzip {V} { return [list $V] } # example how the function looks for N=2 proc ::unlzip::arity2unlzip {V} { foreach {v1 v2} $V { lappend lv1 $v1 lappend lv2 $v2 } return [list $lv1 $lv2] } </code></pre> <p>The disassambled bytecode for Tcl 8.6 for the N=3 proc would look like this (via Tcl 8.6. <code>::tcl::unsupported::disassemble proc</code>:</p> <pre><code>ByteCode 0x00667988, refCt 1, epoch 5, interp 0x005E0B70 (epoch 5) Source "foreach {v0 v1 v2} $V { \n\t lappend lv0 $v0\n\t " Cmds 6, src 149, inst 86, litObjs 1, aux 1, stkDepth 3, code/src 0.00 Proc 0x00694368, refCt 1, args 1, compiled locals 9 slot 0, scalar, arg, "V" slot 1, scalar, temp slot 2, scalar, temp slot 3, scalar, "v0" slot 4, scalar, "v1" slot 5, scalar, "v2" slot 6, scalar, "lv0" slot 7, scalar, "lv1" slot 8, scalar, "lv2" Exception ranges 1, depth 1: 0: level 0, loop, pc 17-57, continue 10, break 61 Commands 6: 1: pc 0-63, src 0-94 2: pc 17-30, src 32-46 3: pc 31-44, src 55-69 4: pc 45-57, src 78-93 5: pc 64-84, src 120-148 6: pc 73-83, src 128-147 Command 1: "foreach {v0 v1 v2} $V { \n\t lappend lv0 $v0\n\t " (0) loadScalar1 %v0 # var "V" (2) storeScalar1 %v1 # temp var 1 (4) pop (5) foreach_start4 0 [data=[%v1], loop=%v2 it%v1 [%v3, %v4, %v5]] (10) foreach_step4 0 [data=[%v1], loop=%v2 it%v1 [%v3, %v4, %v5]] (15) jumpFalse1 +46 # pc 61 Command 2: "lappend lv0 $v0" (17) startCommand +13 1 # next cmd at pc 30 (26) loadScalar1 %v3 # var "v0" (28) lappendScalar1 %v6 # var "lv0" (30) pop Command 3: "lappend lv1 $v1" (31) startCommand +13 1 # next cmd at pc 44 (40) loadScalar1 %v4 # var "v1" (42) lappendScalar1 %v7 # var "lv1" (44) pop Command 4: "lappend lv2 $v2 " (45) startCommand +13 1 # next cmd at pc 58 (54) loadScalar1 %v5 # var "v2" (56) lappendScalar1 %v8 # var "lv2" (58) pop (59) jump1 -49 # pc 10 (61) push1 0 # "" (63) pop Command 5: "return [list $lv0 $lv1 $lv2 ]" (64) startCommand +21 2 # next cmd at pc 85, 2 cmds start here Command 6: "list $lv0 $lv1 $lv2 " (73) loadScalar1 %v6 # var "lv0" (75) loadScalar1 %v7 # var "lv1" (77) loadScalar1 %v8 # var "lv2" (79) list 3 (84) done (85) done </code></pre> <p>As straight forward as it gets..., well, if the lists are incomplete (<code>llength $L</code> modulo <code>$n</code> isn't zero) you would need some little extra checks. As long as the lists are balanced, you could als pre populate the lists and use <code>lset</code> instead of <code>lappend</code>, which is faster, as it doesn't reallocate the list array so often.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload