Updated 2013-11-30 04:41:46 by pooryorick

continue, a built-in tcl command, skips to the next iteration of a loop

see also  edit

break
breakeval
return

loop commands  edit

for
foreach
while

documentation  edit

official reference

synopsis  edit

continue

description  edit

this command is typically invoked inside the body of a looping command such as for or foreach or while. it returns a tcl_continue code, which causes a continue exception to occur. the exception causes the current script to be aborted out to the innermost containing loop command, which then continues with the next iteration of the loop. catch exceptions are also handled in a few other situations, such as the catch command and the outermost scripts of procedure bodies.

examples  edit

print a line for each of the integers from 0 to 10 except 5:
for {set x 0} {$x<10} {incr x} {
    if {$x == 5} {
        continue
    }
    puts "x is $x"
}

discussion  edit

les: suppose the following code:
foreach  i  $list1  { 
    foreach  j  $list2  { 
        if  [some condition] {continue}
        eval {blah blah blah}
    }
}

[continue] interrupts the [foreach] j loop. but what if i wanted it to break the foreach i loop?

place [foreach i]] in a proc and use [return] instead of [continue].

lars h: or use breakeval as follows
foreach i $list1 { 
    breakeval-aware foreach j $list2 { 
        if  {[some condition]} then {
           breakeval {continue} ; # break out of j loop, do a continue for the i loop.
        }
        eval {blah blah blah}
    }
}

mg 2005-04-20: in php, continue (and break) accept an argument that tells it how many nesting levels to continue/break for, slightly-similar to return's -code option. how hard would it be to add something like that into tcl? since neither break nor continue accept any arguments right now, as long as it defaulted to 1 it would have total backwards-compatability, and would, imho, be more "natural" than the above.

schlenk: did you try [return -code continue -level ...]

lars h: that won't work, because it wouldn't become a continue until it returns from some proc.

les: these suggestions all involve creating yet another proc for my code, which is not really what i was looking for. i was indeed thinking of php's continue/break argument, as mg mentioned. i asked the question in the first place because i already have a solution, but it forces me to add more code to an already very long proc that i am trying to do some liposuction on. some sort of "loop depth argument" would help me make it shorter. anyway, here is my current solution:
foreach i $list1 { 
    set  _break  0
    foreach  j  $list2  { 
        if  {[some condition]} {
                        incr _break
                        break 
                }
        eval {blah blah blah}
    }
    if {$_break > 0} continue
        ...
}

conclusion: if you come from php, now you know that there is no continue/break "loop depth argument". but several workarounds are offered above (and below?).

PYK: another kind of sugar:
foreach i $list1 { 
    set continue list
    foreach j $list2  { 
        if  {[some condition]} {
                        set continue continue
                        break 
                }
        eval {blah blah blah}
    }
        $continue
        ...
}

lv: given that there's already the weird return arguments, what is the argument against enhancing continue as described above? is there a technical issue with the proposal?

rhs: the idea of enhancing break and continue to accept an optional depth argument has been brought up multiple times in the past. i've never seen a counter-argument as to why it would be a bad idea... i've never seen anyone with enough motivation to even write up a tip for it either, though. i've had cases where i'd like to have had the feature, and i'm too lazy to write a tip for it, so i can't really complain that someone else hasn't either.

escargo 2005-04-20: in icon, break and next (the equivalent of continue) both have optional expressions that are evaluated in the context outside the current loop. so, if you are in inner loop and you want to leave that one loop, you use break. if you want to leave both an inner and outer loop, you would use break break.

lars h: there is such an rfe logged for tcl [1].