Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/I+love+foreach?V=64
QUERY_STRINGV=64
CONTENT_TYPE
DOCUMENT_URI/revision/I+love+foreach
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.70.43.91
REMOTE_PORT60314
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR44.192.75.131
HTTP_CF_RAY86bafb60eb123b95-IAD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTclaudebot
HTTP_CF_CONNECTING_IP44.192.75.131
HTTP_CDN_LOOPcloudflare
HTTP_CF_IPCOUNTRYUS

Body


Error

Unknow state transition: LINE -> END

-code

1

-level

0

-errorstack

INNER {returnImm {Unknow state transition: LINE -> END} {}} CALL {my render_wikit {I love foreach} {[Keith Vetter] 2003-09-29 -- I love Tcl's [foreach] command. It's a
beautiful command that lets you express elegantly some otherwise
cumbersome constructs. Compared to similar constructs in other languages,
Tcl's foreach command outshines them all.

People often complain that Tcl's ''simple'' syntax can be annoying--it's
prolix and confusing to the initiate: when is a comment a comment? (even
[JO] got that one wrong), always having to use [expr] to do any math,
the whole [{*}] debate ([DISCUSSION: Argument Expansion Syntax]), etc.

But the foreach command is one of Tcl's strengths.

Most of the common uses of foreach such as walking a list, swapping
two variables
   foreach {a b} [list $b $a] break
     -or-
   foreach a $b b $a break

, handling multiple return values from a function (see
[foreach] for more details) have similar constructs in other
languages, often times more elegantly expressed. - ''[RS]: Note that the elegant second form requires a and b to be scalars or empty lists.''

But once you get past these simple uses of foreach, other languages
can't compare. Take even the simple example of traipsing down a
list--in tcl you can take bigger steps. Try doing this in perl (without
destroying the data list):

 foreach {x y} $dataSet { ... }

Another simple (but I admit dubious) use of foreach is setting
multiple variables at once:

 foreach x [$w canvasx $x] y [$w canvasy $y] break

([FW]: wouldn't that rather be
  foreach {x y} [list [$w canvasx $x] [$w canvasy $y]] break
? -- [RS]: Both have the same effect, but the first "multilist" approach is a bit shorter.)

more detailed foreach can be used to extract list structure and simulate [perl] or [haskell] list asigments
In Perl
 ($first,$secound,$third) = @list;
In Tcl common
  set first [lindex $list 0]
  set secound [lindex $list 1]
  set third [lindex $list 2]
or with foreach
  foreach {first secound third} $list {}
the problem of this command is that primary invention (assigment) is not obviously. Everyone await some kind of looping. [KPV] I disagree, it's a Tcl idiom that people come to quickly understand.

But advanced use of foreach that many people don't realize comes
when you traipse over a list of variable '''names'''. Below is
an example from a program I wrote that cleans up user supplied data:

 foreach var {north south east west altitude} {
     set $var [::Data::Fix [set $var]]
 }

Here's an example I just used today:

 foreach col [list red white blue white red] d {4 3 2 1 0} {
    set xy [MakeBox 50 50 [expr {5+$d*8}]]
    .c create oval $xy -fill $col -outline $col
 }

Here's a more complicated example:

 # Get canvas dimensions shrunk by some amount
 foreach who {x0 y0 x1 y1} val [.c cget -scrollregion] d {30 20 -30 -20} {
     set $who [expr {$val + $d}]
 }


Now that I've admitted my love of the foreach command, I confess I
have two complaints. First, I'd love some kind of iteration counter. But
the obvious way of doing that is via a special variable and that not the
''Tcl way''. Second, I'd love foreach to understand [streams], but that's
a whole other discussion.

''Could iteration be done with an extra var running over a generated list of ints? -[jcw]''

[KPV] -- definitely yes, especially if that list of ints were a stream. But the problem is knowing when to stop. The best I could
come up with is below, but sometimes $myList is a function return
value and then this doesn't work as well:

   foreach var $myList cnt [range 0 [llength $myList]] {...}
[RS] does integer iteration like this, admittedly not very tricky:
 set i -1
 foreach element $list {
    incr i ;# safer here than in the end, because the loop might be left early w. continue
    # do something with $element and $i here
 }

[glennj]: or even fall back to the venerable [for] command
 for {set i 0} {$i < [llength $myList]} {incr i} {
     set element [lindex $myList $i]
     # do something with $element and $i here
 }

[KPV]: yes, but by using [for] you lose all the special features
of [foreach] like grabbing multiple elements or traipsing multiple
lists.

[DKF]: The point when you need [for] is when you need to stride over list elements by variable amounts (e.g. when parsing getargs()-style arguments).  At that point, you've no real choice.

[jcw] - That's a good example of why [streams] (and coroutines) are more than a gimmick.  You can consume items ''from different parts in the code'', and therefore at varying "burn rates".  Using some pseudo notation:
    geteach x $argvstream {
      switch -- $x {
        -a { ... }
        -b { set y [get $argvstream]; ... }
      }
    }
Just like "gets" from a channel, really.

[EB]: Keith, you want something like [iterators] ? [KPV] I think so,
it seems to me that iterators and streams are different names for
the same concept.

Anyway C# has now foreach too. It must be good :). The main advantage of foreach is that input for processing and processing variable is good to see. (That is not by for.) Also many errors in 'for' loops (starting value, end or break condition) can be eleminated.

To have index in the looping [Smalltalk] collections have extra command 'doWithIndex:' that provide extra index variable
   list doWithIndex: [:each :index |  Transcript show: each printString , ' index ' , index printString; cr].
That can be also simulated in Tcl as new command
   foreachWithIndex e $list {
      puts "$e index $index"
   }
Unfortunately it would be slower as 'foreach' or 'for' that are special byte-coded for speed by interpreter.
Here sample implementation of 'foreachWithIndex' in simple (not full foreach) syntax.
 proc foreachWithIndex {var_ref list command} {
    upvar $var_ref var
    upvar index uindex
    set uindex 0
    foreach a $list {
        set var $a
        uplevel $command
        incr uindex
    }
 }

[Stu] (2005/12/22) Taking '''foreachWithIndex''' a step further, '''traverse''' will traverse a list, maintain an index count, return the remainder of the list if the entire list was not processed and optionally '''[unset]''' the element var and/or index var.

 proc traverse {var list index body args} {
        upvar 1 $var v
        upvar 1 $index i
        set i -1
        set ii $i
        foreach v $list {
                set i $ii ;# in case the {body} [unset]s 'i'
                incr i    ;# safer here than in the end, because the loop might be left early w. continue (Thanks RS)
                set ii $i
                uplevel 1 $body
        }
        set i $ii ;# in case the {body} [unset]s 'i'
        set ii [incr i]
        foreach a $args {
                if {$a eq {-var}} {
                        unset -nocomplain v ;# '-nocomplain' in case the {body} [unset]s 'v'
                } elseif {$a eq {-index}} {
                        unset i
                }
        }
        return [lrange $list $ii end] ;# (rmax suggested this)
 }


 set lst [list a b c d e]

 puts [traverse elem $lst ind {
        puts "elem:$elem ind:$ind"
        if {$ind > 1} { break }
 } -var -index]

[Stu] (2006/01/02) A better version.

 proc traverse {var list index body args} {
        set cmd "set $index -1\n"
        append cmd "foreach $var [list $list] \{\n\tincr $index\n$body\n\}\n"
        append cmd "lrange [list $list] \[incr $index\] end"
        foreach a $args {
                if {$a eq {-var}} {
                        append cmd "\[unset -nocomplain $var\]"
                } elseif {$a eq {-index}} {
                        append cmd "\[unset -nocomplain $index\]"
                }
        }
        uplevel 1 $cmd
 }
----

[Lars H]: One thought about wanting to "vary the burn rate" -- is there
anything which prevents this? I notice (in tclCompile.h) that there are two
distinct instructions INST_FOREACH_START4 and INST_FOREACH_STEP4 (although
I don't know how one figures out what they do), so what would happen if
"foreach step" could appear in the middle of a foreach body? Would that
have effects like those of [jcw]'s "get" above?

Assuming the answer is yes, here is some pseudo-code exploiting the idea.
It implements a simple drawing language where the commands and their
arguments are just elements in a list with no particular structure.
I'm using the name '''next''' for the step-foreach-command.

  foreach cmd $cmdargseq {
     switch -- $cmd {
        line {
           next {x1 y1 x2 y2}
           $canvas create line $x1 $y1 $x2 $y2
        }
        circle {
           next {x y radius}
           $canvas create oval [expr {$x-$radius}] [expr {$y-$radius}] [expr {$x+$radius}] [expr {$y+$radius}]
        }
     }
  }

A $cmdargseq of "circle 20 20 15 line 18 2 10 10" should then boil down to
  $canvas create oval 5 5 35 35
  $canvas create line 18 2 10 10
Of course, the most important application would probably not be executing
code from such mini-languages (although I've had to do write Tcl code for
that on some occations, and would have found this '''next''' very useful
then), but parsing options of Tcl procedures (although that is a kind of mini-language too).

[DKF]: While in theory you could put INST_FOREACH_STEP in the middle of the loop, you'd need to define what happens if that reaches the end of the list at that point. You'd also need to say why just going round the loop again is not good ehough...

[Lars H]: The "why not go around the loop again" question has an easy answer: the resulting code gets an unintuitive structure that is hard to understand (just try rewriting the short example above!). I certainly can do (and have done) that, but it's not particularly elegant. As for what the '''next''' should do, there are two possibilities: either it sets the extra variables to empty strings or it terminates the loop like a [break]. In the case of a multi-list [foreach] the loop should only be terminated if all lists have ended, so there is a certain bias towards the empty string alternative being to more natural one. Right now I'm most inclined to suggest that '''next''' should never break, but instead (like [scan]) return the number of variables that were set to elements from the list. Whether INST_FOREACH_STEP does anything like that is another matter, but its existence suggests that a bytecode command doing this with a [foreach] loop is possible.

[NEM]: I'd vote for next throwing an error if there are not enough elements left in the
list to fill all the variables asked for. I'm not sure how next would work at all when multiple
lists are being iterated over -- how does it know which list to consume from?

Regarding your specific example, you can have fun with code like the following:

 pack [canvas .c] -fill both -expand 1
 proc line {x1 y1 x2 y2 args} {
     .c create line $x1 $y1 $x2 $y2
     return $args
 }
 proc circle {x y r args} {
     .c create oval [expr {$x-$r}] [expr {$y-$r}] [expr {$x+$r}] [expr {$y+$r}]
     return $args
 }
 proc iterate cmds {
     while {[llength $cmds]} { set cmds [uplevel #0 $cmds] }
 }
 iterate [list circle 20 20 15 line 18 2 10 10]

[RS] feels reminded of [Turtle graphics the LOGO way] ... - the ''return $args'' pattern is very Logo-like :)
----
[slebetman]: Talking about "varying burn rate" again, the '''iterate''' proc above is close to what I normally use to do it. That is, instead of using the '''for''' loop I usually [Use while to iterate over a list]
----
[Sly]: Let me add one more use case.
I use foreach to check for existing array keys and do something with it.

 foreach x [array names a ABC] { ; # the key ABC is in here
   ...
 }

----
[FB]: Scheme-style lazy and infinite lists are great alternatives to generators and iterators when used with `[foreach]`. As part of the [Cloverfield] project I tried to define a syntax that allows circular references and delayed evaluations (see [Cloverfield], section '''References'''). For example, the following defines an infinite list of "a" strings, which can be used with `[foreach]` (this would obviously loop indefinitely, but you see the point):

======
{ref root}(a {*}{ref root}{})
======

Moreover, [Cloverfield] also provides delayed evaluation. Combined with argument expansion this can also give interesting results. The following defines an infinite list whose elements are a lazily computed sequence of consecutive integers using continuations:

======
proc getNext {i} {
    return ($i {*}{delay}[getNext [expr {$i+1}]])
}
foreach i [getNext 1] {
    # Iterates over all consecutive integers starting from 1.
}
======
----
[EKB] While not quite the same thing, I wanted to try a pure-Tcl approach to implicitly-defined infinite lists. Here's what I came up with. First, here's the code, a helper proc called "do_implicit" and then the command-creating proc "implicit":
 proc do_implicit {exprs list} {
    upvar $list vals
    array set earray $exprs
    set n [llength $vals]
    if {$n in [array names earray]} {
        set nextval [expr $earray($n)]
    } else {
        set e $earray(default)
        # Add a dummy end to list, then get rid of it
        lappend vals dummy
        regsub -all -- {<-([0-9]+)>} $e {[lindex $vals end-\1]} e
        set nextval [expr $e]
        set vals [lrange $vals 0 end-1]
    }
    lappend vals $nextval
    return $nextval
 }

 proc implicit {name exprs} {
    proc $name list "upvar \$list list2; do_implicit [list $exprs] list2"
 }

This can be used to implicitly define functions that in principle generate infinite lists:
 implicit Fibonacci {
    0 {1}
    1 {2}
    default {<-1> + <-2>}
 }

where <-n> means "use the value calculated n steps prior to this one". (Actually, the Fibonacci series is 0, 1, 1, 2, ... For this example I start with the third element, 1, 2, ... This is just so the example farther down makes some sense.)

Then this can be used the following way:
 % set mylist {}
 % while {[Fibonacci mylist] < 30} {}
 % set mylist
 1 2 3 5 8 13 21 34

Note that it goes one element past the value being tested for (< 30), so if that last value isn't wanted it must be dropped.

So, while this is a bit verbose, here's a way to use [foreach]:
 % set mylist {}
 % while {[Fibonacci mylist] < 30} {}
 % foreach n [lrange $mylist 0 end-1] {if {$n == 1} {puts "$n day"} else {puts "$n days"}}
 1 day
 2 days
 3 days
 5 days
 8 days
 13 days
 21 days

That way, if you like to use Fibonacci numbers of days for task planning, you have a nice list of days to work with!

And with this proc,
 proc all {name rel val} {
    set list {}
    while "\[\$name list\] $rel \$val" {}
    lrange $list 0 end-1
 }
it can all be done in one line:
 % foreach n [all Fibonacci < 30] {if {$n == 1} {puts "$n day"} else {puts "$n days"}}

[EKB] Also see [Lazy Lists].











======
----
***Screenshots***








[http://farm5.static.flickr.com/4058/4688331888_483eacbbd7_s.jpg]






[http://farm5.static.flickr.com/4058/4688331888_483eacbbd7.jpg]
 alt="TCL_WIKI_iterateovalcommandtest5pix by you."
 [farm5.static.flickr.com/4058/4688331888_483eacbbd7_t.jpg]
                        


                        









[gold] added pix,  canvas with [NEM]'s iterate oval function above   

    
----








----
!!!!!!
%|[Category Control Structure] | [Category Example]|%
!!!!!!} regexp2} CALL {my render {I love foreach} {[Keith Vetter] 2003-09-29 -- I love Tcl's [foreach] command. It's a
beautiful command that lets you express elegantly some otherwise
cumbersome constructs. Compared to similar constructs in other languages,
Tcl's foreach command outshines them all.

People often complain that Tcl's ''simple'' syntax can be annoying--it's
prolix and confusing to the initiate: when is a comment a comment? (even
[JO] got that one wrong), always having to use [expr] to do any math,
the whole [{*}] debate ([DISCUSSION: Argument Expansion Syntax]), etc.

But the foreach command is one of Tcl's strengths.

Most of the common uses of foreach such as walking a list, swapping
two variables
   foreach {a b} [list $b $a] break
     -or-
   foreach a $b b $a break

, handling multiple return values from a function (see
[foreach] for more details) have similar constructs in other
languages, often times more elegantly expressed. - ''[RS]: Note that the elegant second form requires a and b to be scalars or empty lists.''

But once you get past these simple uses of foreach, other languages
can't compare. Take even the simple example of traipsing down a
list--in tcl you can take bigger steps. Try doing this in perl (without
destroying the data list):

 foreach {x y} $dataSet { ... }

Another simple (but I admit dubious) use of foreach is setting
multiple variables at once:

 foreach x [$w canvasx $x] y [$w canvasy $y] break

([FW]: wouldn't that rather be
  foreach {x y} [list [$w canvasx $x] [$w canvasy $y]] break
? -- [RS]: Both have the same effect, but the first "multilist" approach is a bit shorter.)

more detailed foreach can be used to extract list structure and simulate [perl] or [haskell] list asigments
In Perl
 ($first,$secound,$third) = @list;
In Tcl common
  set first [lindex $list 0]
  set secound [lindex $list 1]
  set third [lindex $list 2]
or with foreach
  foreach {first secound third} $list {}
the problem of this command is that primary invention (assigment) is not obviously. Everyone await some kind of looping. [KPV] I disagree, it's a Tcl idiom that people come to quickly understand.

But advanced use of foreach that many people don't realize comes
when you traipse over a list of variable '''names'''. Below is
an example from a program I wrote that cleans up user supplied data:

 foreach var {north south east west altitude} {
     set $var [::Data::Fix [set $var]]
 }

Here's an example I just used today:

 foreach col [list red white blue white red] d {4 3 2 1 0} {
    set xy [MakeBox 50 50 [expr {5+$d*8}]]
    .c create oval $xy -fill $col -outline $col
 }

Here's a more complicated example:

 # Get canvas dimensions shrunk by some amount
 foreach who {x0 y0 x1 y1} val [.c cget -scrollregion] d {30 20 -30 -20} {
     set $who [expr {$val + $d}]
 }


Now that I've admitted my love of the foreach command, I confess I
have two complaints. First, I'd love some kind of iteration counter. But
the obvious way of doing that is via a special variable and that not the
''Tcl way''. Second, I'd love foreach to understand [streams], but that's
a whole other discussion.

''Could iteration be done with an extra var running over a generated list of ints? -[jcw]''

[KPV] -- definitely yes, especially if that list of ints were a stream. But the problem is knowing when to stop. The best I could
come up with is below, but sometimes $myList is a function return
value and then this doesn't work as well:

   foreach var $myList cnt [range 0 [llength $myList]] {...}
[RS] does integer iteration like this, admittedly not very tricky:
 set i -1
 foreach element $list {
    incr i ;# safer here than in the end, because the loop might be left early w. continue
    # do something with $element and $i here
 }

[glennj]: or even fall back to the venerable [for] command
 for {set i 0} {$i < [llength $myList]} {incr i} {
     set element [lindex $myList $i]
     # do something with $element and $i here
 }

[KPV]: yes, but by using [for] you lose all the special features
of [foreach] like grabbing multiple elements or traipsing multiple
lists.

[DKF]: The point when you need [for] is when you need to stride over list elements by variable amounts (e.g. when parsing getargs()-style arguments).  At that point, you've no real choice.

[jcw] - That's a good example of why [streams] (and coroutines) are more than a gimmick.  You can consume items ''from different parts in the code'', and therefore at varying "burn rates".  Using some pseudo notation:
    geteach x $argvstream {
      switch -- $x {
        -a { ... }
        -b { set y [get $argvstream]; ... }
      }
    }
Just like "gets" from a channel, really.

[EB]: Keith, you want something like [iterators] ? [KPV] I think so,
it seems to me that iterators and streams are different names for
the same concept.

Anyway C# has now foreach too. It must be good :). The main advantage of foreach is that input for processing and processing variable is good to see. (That is not by for.) Also many errors in 'for' loops (starting value, end or break condition) can be eleminated.

To have index in the looping [Smalltalk] collections have extra command 'doWithIndex:' that provide extra index variable
   list doWithIndex: [:each :index |  Transcript show: each printString , ' index ' , index printString; cr].
That can be also simulated in Tcl as new command
   foreachWithIndex e $list {
      puts "$e index $index"
   }
Unfortunately it would be slower as 'foreach' or 'for' that are special byte-coded for speed by interpreter.
Here sample implementation of 'foreachWithIndex' in simple (not full foreach) syntax.
 proc foreachWithIndex {var_ref list command} {
    upvar $var_ref var
    upvar index uindex
    set uindex 0
    foreach a $list {
        set var $a
        uplevel $command
        incr uindex
    }
 }

[Stu] (2005/12/22) Taking '''foreachWithIndex''' a step further, '''traverse''' will traverse a list, maintain an index count, return the remainder of the list if the entire list was not processed and optionally '''[unset]''' the element var and/or index var.

 proc traverse {var list index body args} {
        upvar 1 $var v
        upvar 1 $index i
        set i -1
        set ii $i
        foreach v $list {
                set i $ii ;# in case the {body} [unset]s 'i'
                incr i    ;# safer here than in the end, because the loop might be left early w. continue (Thanks RS)
                set ii $i
                uplevel 1 $body
        }
        set i $ii ;# in case the {body} [unset]s 'i'
        set ii [incr i]
        foreach a $args {
                if {$a eq {-var}} {
                        unset -nocomplain v ;# '-nocomplain' in case the {body} [unset]s 'v'
                } elseif {$a eq {-index}} {
                        unset i
                }
        }
        return [lrange $list $ii end] ;# (rmax suggested this)
 }


 set lst [list a b c d e]

 puts [traverse elem $lst ind {
        puts "elem:$elem ind:$ind"
        if {$ind > 1} { break }
 } -var -index]

[Stu] (2006/01/02) A better version.

 proc traverse {var list index body args} {
        set cmd "set $index -1\n"
        append cmd "foreach $var [list $list] \{\n\tincr $index\n$body\n\}\n"
        append cmd "lrange [list $list] \[incr $index\] end"
        foreach a $args {
                if {$a eq {-var}} {
                        append cmd "\[unset -nocomplain $var\]"
                } elseif {$a eq {-index}} {
                        append cmd "\[unset -nocomplain $index\]"
                }
        }
        uplevel 1 $cmd
 }
----

[Lars H]: One thought about wanting to "vary the burn rate" -- is there
anything which prevents this? I notice (in tclCompile.h) that there are two
distinct instructions INST_FOREACH_START4 and INST_FOREACH_STEP4 (although
I don't know how one figures out what they do), so what would happen if
"foreach step" could appear in the middle of a foreach body? Would that
have effects like those of [jcw]'s "get" above?

Assuming the answer is yes, here is some pseudo-code exploiting the idea.
It implements a simple drawing language where the commands and their
arguments are just elements in a list with no particular structure.
I'm using the name '''next''' for the step-foreach-command.

  foreach cmd $cmdargseq {
     switch -- $cmd {
        line {
           next {x1 y1 x2 y2}
           $canvas create line $x1 $y1 $x2 $y2
        }
        circle {
           next {x y radius}
           $canvas create oval [expr {$x-$radius}] [expr {$y-$radius}] [expr {$x+$radius}] [expr {$y+$radius}]
        }
     }
  }

A $cmdargseq of "circle 20 20 15 line 18 2 10 10" should then boil down to
  $canvas create oval 5 5 35 35
  $canvas create line 18 2 10 10
Of course, the most important application would probably not be executing
code from such mini-languages (although I've had to do write Tcl code for
that on some occations, and would have found this '''next''' very useful
then), but parsing options of Tcl procedures (although that is a kind of mini-language too).

[DKF]: While in theory you could put INST_FOREACH_STEP in the middle of the loop, you'd need to define what happens if that reaches the end of the list at that point. You'd also need to say why just going round the loop again is not good ehough...

[Lars H]: The "why not go around the loop again" question has an easy answer: the resulting code gets an unintuitive structure that is hard to understand (just try rewriting the short example above!). I certainly can do (and have done) that, but it's not particularly elegant. As for what the '''next''' should do, there are two possibilities: either it sets the extra variables to empty strings or it terminates the loop like a [break]. In the case of a multi-list [foreach] the loop should only be terminated if all lists have ended, so there is a certain bias towards the empty string alternative being to more natural one. Right now I'm most inclined to suggest that '''next''' should never break, but instead (like [scan]) return the number of variables that were set to elements from the list. Whether INST_FOREACH_STEP does anything like that is another matter, but its existence suggests that a bytecode command doing this with a [foreach] loop is possible.

[NEM]: I'd vote for next throwing an error if there are not enough elements left in the
list to fill all the variables asked for. I'm not sure how next would work at all when multiple
lists are being iterated over -- how does it know which list to consume from?

Regarding your specific example, you can have fun with code like the following:

 pack [canvas .c] -fill both -expand 1
 proc line {x1 y1 x2 y2 args} {
     .c create line $x1 $y1 $x2 $y2
     return $args
 }
 proc circle {x y r args} {
     .c create oval [expr {$x-$r}] [expr {$y-$r}] [expr {$x+$r}] [expr {$y+$r}]
     return $args
 }
 proc iterate cmds {
     while {[llength $cmds]} { set cmds [uplevel #0 $cmds] }
 }
 iterate [list circle 20 20 15 line 18 2 10 10]

[RS] feels reminded of [Turtle graphics the LOGO way] ... - the ''return $args'' pattern is very Logo-like :)
----
[slebetman]: Talking about "varying burn rate" again, the '''iterate''' proc above is close to what I normally use to do it. That is, instead of using the '''for''' loop I usually [Use while to iterate over a list]
----
[Sly]: Let me add one more use case.
I use foreach to check for existing array keys and do something with it.

 foreach x [array names a ABC] { ; # the key ABC is in here
   ...
 }

----
[FB]: Scheme-style lazy and infinite lists are great alternatives to generators and iterators when used with `[foreach]`. As part of the [Cloverfield] project I tried to define a syntax that allows circular references and delayed evaluations (see [Cloverfield], section '''References'''). For example, the following defines an infinite list of "a" strings, which can be used with `[foreach]` (this would obviously loop indefinitely, but you see the point):

======
{ref root}(a {*}{ref root}{})
======

Moreover, [Cloverfield] also provides delayed evaluation. Combined with argument expansion this can also give interesting results. The following defines an infinite list whose elements are a lazily computed sequence of consecutive integers using continuations:

======
proc getNext {i} {
    return ($i {*}{delay}[getNext [expr {$i+1}]])
}
foreach i [getNext 1] {
    # Iterates over all consecutive integers starting from 1.
}
======
----
[EKB] While not quite the same thing, I wanted to try a pure-Tcl approach to implicitly-defined infinite lists. Here's what I came up with. First, here's the code, a helper proc called "do_implicit" and then the command-creating proc "implicit":
 proc do_implicit {exprs list} {
    upvar $list vals
    array set earray $exprs
    set n [llength $vals]
    if {$n in [array names earray]} {
        set nextval [expr $earray($n)]
    } else {
        set e $earray(default)
        # Add a dummy end to list, then get rid of it
        lappend vals dummy
        regsub -all -- {<-([0-9]+)>} $e {[lindex $vals end-\1]} e
        set nextval [expr $e]
        set vals [lrange $vals 0 end-1]
    }
    lappend vals $nextval
    return $nextval
 }

 proc implicit {name exprs} {
    proc $name list "upvar \$list list2; do_implicit [list $exprs] list2"
 }

This can be used to implicitly define functions that in principle generate infinite lists:
 implicit Fibonacci {
    0 {1}
    1 {2}
    default {<-1> + <-2>}
 }

where <-n> means "use the value calculated n steps prior to this one". (Actually, the Fibonacci series is 0, 1, 1, 2, ... For this example I start with the third element, 1, 2, ... This is just so the example farther down makes some sense.)

Then this can be used the following way:
 % set mylist {}
 % while {[Fibonacci mylist] < 30} {}
 % set mylist
 1 2 3 5 8 13 21 34

Note that it goes one element past the value being tested for (< 30), so if that last value isn't wanted it must be dropped.

So, while this is a bit verbose, here's a way to use [foreach]:
 % set mylist {}
 % while {[Fibonacci mylist] < 30} {}
 % foreach n [lrange $mylist 0 end-1] {if {$n == 1} {puts "$n day"} else {puts "$n days"}}
 1 day
 2 days
 3 days
 5 days
 8 days
 13 days
 21 days

That way, if you like to use Fibonacci numbers of days for task planning, you have a nice list of days to work with!

And with this proc,
 proc all {name rel val} {
    set list {}
    while "\[\$name list\] $rel \$val" {}
    lrange $list 0 end-1
 }
it can all be done in one line:
 % foreach n [all Fibonacci < 30] {if {$n == 1} {puts "$n day"} else {puts "$n days"}}

[EKB] Also see [Lazy Lists].











======
----
***Screenshots***








[http://farm5.static.flickr.com/4058/4688331888_483eacbbd7_s.jpg]






[http://farm5.static.flickr.com/4058/4688331888_483eacbbd7.jpg]
 alt="TCL_WIKI_iterateovalcommandtest5pix by you."
 [farm5.static.flickr.com/4058/4688331888_483eacbbd7_t.jpg]
                        


                        









[gold] added pix,  canvas with [NEM]'s iterate oval function above   

    
----








----
!!!!!!
%|[Category Control Structure] | [Category Example]|%
!!!!!!}} CALL {my revision {I love foreach}} CALL {::oo::Obj1133978 process revision/I+love+foreach} CALL {::oo::Obj1133976 process}

-errorcode

NONE

-errorinfo

Unknow state transition: LINE -> END
    while executing
"error $msg"
    (class "::Wiki" method "render_wikit" line 6)
    invoked from within
"my render_$default_markup $N $C $mkup_rendering_engine"
    (class "::Wiki" method "render" line 8)
    invoked from within
"my render $name $C"
    (class "::Wiki" method "revision" line 31)
    invoked from within
"my revision $page"
    (class "::Wiki" method "process" line 56)
    invoked from within
"$server process [string trim $uri /]"

-errorline

4