Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/for?V=43
QUERY_STRINGV=43
CONTENT_TYPE
DOCUMENT_URI/revision/for
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.69.59.130
REMOTE_PORT52274
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR3.145.12.242
HTTP_CF_RAY87a4e4c2cf7e1167-ORD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTMozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected])
HTTP_CF_CONNECTING_IP3.145.12.242
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 for '''\[http://www.tcl.tk/man/tcl/TclCmd/for.htm%|%for\]''',\ a\ \[Tcl\ Commands%|%built-in\]\ \[Tcl\]\ command,\ provides\ an\ iterative\ loop\ construct.\n\n\n\n**\ See\ Also\ **\n\n\ \ \ \[break\]:\ \ \ \n\n\ \ \ \[continue\]:\ \ \ \n\n\ \ \ \[expr\]:\ \ \ \n\n\ \ \ \[foreach\]:\ \ \ \n\n\ \ \ \[if\]:\ \ \ \n\n\ \ \ \[while\]:\ \ \ \n\n\ \ \ \[fold\]\ /\ \[map\]\ /\ \[zip\]\ etc:\ \ \ \n\n\ \ \ \[for\ in%|%for\ ...\ in\]:\ \ \ \n\n\n\n**\ Synopsis\ **\n\n'''for'''\ ''start\ test\ next\ body''\n\n\n\n**\ Documentation\ **\n\n\ \ \ \[http://www.tcl.tk/man/tcl/TclCmd/for.htm%|%official\ reference\]:\ \ \ \n\n\n\n**\ Description\ **\n\n'''For'''\ is\ a\ looping\ command,\ similar\ in\ structure\ to\ the\ C\ '''for'''\nstatement.\ \ The\ ''start'',\ ''next'',\ and\ ''body''\ arguments\ are\ scripts\nstatement.\ \ The\ ''start'',\ ''next'',\ and\ ''body''\ arguments\ must\ be\ Tcl\ command\nstrings,\ and\ ''test''\ is\ an\ \[\[`\[expr\]`\]\ argument.\ \[\[`for`\]\ first\ invokes\ the\nTcl\ interpreter\ to\ execute\ ''start''.\ \ Then\ it\ iteratively\ evaluates\ ''test''\nas\ an\ expression,\ and\ if\ the\ result\ is\ non-zero,\ then\ evaluates\ ''body''\ as\ a\nTcl\ script.\ \ Finally,\ it\ evaluates\ ''next''\ as\ a\ Tcl\ script,\ and\ then\ repeats\nthe\ loop.\n`\[continue\]`\ and\ `\[break\]`\ function\ in\ a\ manner\ similar\ to\ the\ corresponding\n\[\[`for`\]\ terminates\ when\ ''test''\ evaluates\ to\ `0`.\ \ If\ a\ \[\[`\[continue\]`\]\ is\ninvoked\ within\ ''body''\ then\ any\ remaining\ commands\ in\ the\ current\ evalutaion\nof\ ''body''\ are\ skipped,\ \ ''next''\ is\ evaluated\ as\ a\ Tcl\ script,\ ''test''\ is\nagain\ evaluated,\ and\ so\ on.\ \ If\ \[\[`\[break\]`\]\ is\ invoked\ within\ ''body''\ or\n''next'',\ \[\[`for`\]\ returns\ immediately.\ \ \[\[`\[break\]`\]\ and\ \[\[`\[continue\]`\]\nfunction\ in\ a\ manner\ similar\ to\ the\ corresponding\ statements\ in\ C.\ \[\[`for`\]\nreturns\ an\ empty\ string.\ \n`for`\ returns\ an\ empty\ string.\ \n''test''\ should\ almost\ always\ be\ enclosed\ in\ braces.\ \ If\ not,\ variable\nsubstitutions\ will\ be\ made\ by\ Tcl\ before\ it\ calls\ \[\[`for`\],\ causing\ \[\[`for`\]\ to\nsee\ the\ value\ intead\ of\ the\ variable,\ and\ preventing\ it\ from\ detecting\ changes\nmade\ to\ the\ variable\ in\ ''body''.\ \ This\ is\ likely\ to\ result\ in\ an\ infinite\nloop,\ and\ to\ the\ possibility\ of\ unintended\ effects\ from\ \[double\ substitution\].\nIf\ ''test''\ is\ enclosed\ in\ braces,\ Tcl\ does\ not\ perform\ substitutions\ on\ it\ and\ntherefore\ does\ not\ step\ on\ the\ toes\ of\ \[\[`if`\]\ as\ it\ uses\ \[\[`\[expr\]`\]\ to\nperfrom\ its\ own\ substitutions.\ \ For\ an\ example,\ try\ the\ following\ script\ with\nand\ without\ the\ braces\ around\ `\$x<10`:\ \n''test''\ should\ almost\ always\ be\ enclosed\ in\ braces.\ \ Otherwise,\ substitutions\nfor\ \{set\ x\ 0\}\ \{\$x<10\}\ \{incr\ x\}\ \{\n\ \ \ \ puts\ \"x\ is\ \$x\"\n\}\n======\n\nSee\ also:\ \[TclHelp\]\n\n\n\n**\ `for`\ vs\ `\[foreach\]`\ **\n**\ \[\[`\[for\]`\]\ vs\ \[\[`\[foreach\]`\]\ **\n`\[foreach\]`\ is\ generally\ better\ style\ for\ non-numeric\ looping.\ Those\n\[\[`\[foreach\]`\]\ is\ generally\ better\ style\ for\ non-numeric\ looping.\ Those\nbecause\ they\ think\ of\ an\ indexed\ array\ where\ a\ Tcl\ programmer\ writes:\n\n======\nset\ color_list\ \"red\ blue\ umber\ mauve\"\nforeach\ color\ \$color_list\ \{...\}\n======\n\nIn\ some\ situations,\ using\ `\[foreach\]`\ with\ a\ fixed\ list\ is\ more\ convenient\nIn\ some\ situations,\ using\ \[\[`\[foreach\]`\]\ with\ a\ fixed\ list\ is\ more\ convenient\nthan\ \[\[`for`\],\ even\ if\ the\ list\ is\ numeric.\ \ Compare:\n======\nforeach\ i\ \{1\ 2\ 3\ 4\ 5\}\ \{...\nfor\ \{set\ i\ 1\}\ \{\$i\ <=\ 5\}\ \{incr\ i\}\ \{...\n======\n\n----\n\nSome\ find\ the\ idea\ of\ using\ `\[foreach\]`\ on\ a\ range\ of\ integers\ so\ nice\ that\nSome\ find\ the\ idea\ of\ using\ \[\[`\[foreach\]`\]\ on\ a\ range\ of\ integers\ so\ nice\ that\nthey\ pour\ some\ sugar\ over\ \[\[`for`\]:\n======\nproc\ range\ \{from\ to:\ to\}\ \{\n\ \ \ \ set\ res\ \[list\]\n\ \ \ \ for\ \{set\ i\ \$from\}\ \{\$i<=\$to\}\ \{incr\ i\}\ \{lappend\ res\ \$i\}\n\ \ \ \ set\ res\n\}\nforeach\ i\ \[range\ 1\ ..\ 5\]\ \{...\n======\n\nThis\ is,\ however,\ slower\ than\ `for`.\nThis\ is,\ however,\ slower\ than\ \[\[`\[for\]`\].\n----\n\nThe\ main\ difference\ between\ `for`\ and\ `\[foreach\]`\ when\ iterating\ over\ a\nThe\ main\ difference\ between\ \[\[`for`\]\ and\ \[\[`\[foreach\]`\]\ when\ iterating\ over\ a\nlist\ is\ that\ with\ \[\[`for`\]\ the\ index\ into\ the\ list\ is\ available,\ whereas\ with\n\[\[`\[foreach\]`\],\ it\ is\ not.\ \ \[\[`\[foreach\]`\]\ can,\ however,\ be\ preferable\ even\ if\nthe\ list\ index\ is\ needed.\ \ What\ would\ traditionally\ be\ coded\ as\n======\nfor\ \{set\ index\ 0\}\ \{\$index\ <\ \[llength\ \$list\]\}\ \{incr\ index\}\ \{\n\ \ \ \ set\ item\ \[lindex\ \$list\ \$index\]\n\ \ \ \ #\ Now\ do\ something\ using\ both\ \$index\ and\ \$item\n\ \ \ \ ...\n\}\n======\n\nis\ actually\ faster\ when\ written\ as\ the\ following\ `\[foreach\]`:\nis\ actually\ faster\ when\ written\ as\ the\ following\ \[\[`\[foreach\]`\]:\n======\nset\ index\ -1\nforeach\ item\ \$list\ \{\n\ \ \ \ incr\ index\n\ \ \ \ \ \ \ \ incr\ index\n\ \ \ \ ...\n\}\n======\n\nIn\ order\ for\ `\[continue\]`\ to\ do\ the\ right\ thing,\ `\[incr\]\ index`\ comes\ first\ in\nThe\ reason\ to\ \[\[`\[incr\]`\]\ ''index''\ first\ in\ the\ loop\ body\ is\ that\ this\ makes\n\[\[`\[continue\]`\]\ do\ the\ right\ thing.\n----\ \n\n\[AMG\]:\ Sometimes\ I\ need\ to\ chew\ through\ a\ list\ and\ conditionally\ edit,\ replace,\nor\ remove\ elements.\ \ I\ can\ easily\ read\ \"copies\"\ of\ each\ element\ in\ the\ list\nusing\ `\[foreach\]`,\ but\ when\ the\ condition\ triggers\ I\ need\ the\ list\ index\nusing\ \[\[`\[foreach\]`\]\],\ but\ when\ the\ condition\ triggers\ I\ need\ the\ list\ index\nfor\ \[\[`\[lreplace\]`\],\ \[\[`\[lset\]`\],\ \[\[`\[linsert\]`\],\ and\ the\ like.\ \ What's\ the\n\nOne\ option:\n\n======\nset\ list\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\}\nset\ index\ -1\nforeach\ elem\ \$list\ \{\n\ \ \ \ incr\ index\n\ \ \ \ if\ \{\$elem\ %\ 2\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ lset\ list\ \$index\ \[expr\ \{-\$elem\}\]\n\ \ \ \ \}\n\}\n======\n\nAnother\ option:\n\n======\nset\ list\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\}\nfor\ \{set\ index\ 0\}\ \{\$index\ <\ \[llength\ \$list\]\}\ \{incr\ index\}\ \{\n\ \ \ \ set\ elem\ \[lindex\ \$list\ \$index\]\n\ \ \ \ if\ \{\$elem\ %\ 2\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ lset\ list\ \$index\ \[expr\ \{-\$elem\}\]\n\ \ \ \ \}\n\}\n======\n\nWhich\ is\ preferred?\ \ Here's\ another\ option.\n\n======\nset\ list\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\}\nset\ result\ \[list\]\nforeach\ elem\ \$list\ \{\n\ \ \ \ if\ \{\$elem\ %\ 2\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ lappend\ result\ \[expr\ \{-\$elem\}\]\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ lappend\ result\ \$elem\n\ \ \ \ \}\n\}\nset\ list\ \$result\n======\n\nBetter\ still\ would\ be\ a\ list\ comprehension\ (e.g.,\ `\[lcomp\]`),\ but\ to\ me\ it\nBetter\ still\ would\ be\ a\ list\ comprehension\ (e.g.,\ \[\[`\[lcomp\]`\]),\ but\ to\ me\ it\n\n\[Lars\ H\]:\ Good\ question\;\ I\ often\ find\ myself\ wondering\ the\ same\ thing.\ I\nsuspect\ that\ rebuilding\ the\ list\ is\ on\ the\ whole\ the\ best\ approach,\ when\npossible\ (I\ think\ dragging\ the\ index\ around\ is\ sometimes\ unavoidable).\ An\ nice\nthing\ about\ the\ rebuild\ method\ is\ that\ it\ allows\ for\ more\ functional\ ways\ of\nwriting\ the\ body\;\ in\ this\ case\ the\ extreme\ is\ probably\n\n======\nset\ list\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\}\nset\ result\ \[list\]\nforeach\ elem\ \$list\ \{\n\ \ \ \ lappend\ result\ \[expr\ \{\n\ \ \ \ \ \ \ \ \$elem\ %\ 2\ ==\ 0\ ?\ -\$elem\ :\ \$elem\n\ \ \ \ \}\]\n\}\nset\ list\ \$result\n======\n\n\[AMG\]:\ If\ your\ code\ is\ functional,\ does\ that\ mean\ mine\ is\ dysfunctional?\ :^)\nSeriously,\ we\ should\ look\ into\ list\ comprehensions\ a\ bit\ more.\ \ Just\ how\ much\ndo\ they\ cost,\ when\ implemented\ in\ Tcl\ or\ C?\ \ Can\ something\ be\ done\ in\ C\ to\nallow\ for\ a\ better\ Tcl\ implementation?\ \ How\ do\ list\ comprehensions\ compare\ to\nwriting\ the\ equivalent\ `for`/`\[foreach\]`\ commands?\ \ Which\ is\ more\ readable\nwriting\ the\ equivalent\ \[\['''for'''\]\]s/\[\[\[foreach\]\]\]es?\ \ Which\ is\ more\ readable\n\nWith\ `\[lcomp\]`,\ the\ above\ is\ written:\nWith\ \[\[`\[lcomp\]`\],\ the\ above\ is\ written:\n======\nset\ list\ \[lcomp\ \{\[expr\ \{\$x\ *\ -1\ **\ (1\ -\ \$x\ %\ 2)\}\]\}\ x\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\}\]\n======\n\nYeah,\ maybe\ that\ exponentiation\ is\ going\ overboard,\ but\ I\ couldn't\ help\ myself.\n:^)\n\n\[Lars\ H\]:\ If\ you\ rewrite\ that\ expression\ using\ the\ ?:\ operation,\ you'll\ see\nthat\ my\ code\ was\ just\ an\ unrolled\ version\ of\ your\ `\[lcomp\]`.\ The\ last\ three\nthat\ my\ code\ was\ just\ an\ unrolled\ version\ of\ your\ \[\[`\[lcomp\]`\].\ The\ last\ three\nfunctional\ style.\n\n`\[lcomp\]`\ can\ be\ modified\ to\ `\[eval\]`\ its\ first\ argument,\ perhaps\ in\ a\n\[\[`\[lcomp\]`\]\ can\ be\ modified\ to\ \[\[`\[eval\]`\]\ its\ first\ argument,\ perhaps\ in\ a\nchild\ interpreter\ with\ an\ \[\['''emit'''\]\ command.\ \ That\ would\ allow\ the\ above\ to\n\n======\nset\ list\ \[lcomp\ \{\n\ \ \ \ if\ \{\$x\ %\ 2\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ emit\ \[expr\ \{-\$x\}\]\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ emit\ \$x\n\ \ \ \ \}\n\}\ x\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\}\]\n======\n\nPlus,\ if\ '''`emit`'''\ can\ take\ multiple\ arguments\ and/or\ can\ be\ called\nPlus,\ if\ \[\['''emit'''\]\ can\ take\ multiple\ arguments\ and/or\ can\ be\ called\nnumber\ (including\ zero)\ of\ output\ elements.\ \ Hmm.\n\nHey,\ joyous\ idea.\ \ The\ first\ argument\ gets\ passed\ unmodified\ to\ `\[eval\]`\nHey,\ joyous\ idea.\ \ The\ first\ argument\ gets\ passed\ unmodified\ to\ \[\[`\[eval\]`\]\]\n(or\ \[\[`\[interp\ eval\]`\]\]),\ which\ should\ (??)\ allow\ Tcl\ to\ bytecode\ compile\ it.\nBonus!\ \ But\ the\ nests\ of\ \[\[`\[foreach\]`\]es\ would\ still\ be\ pieced\ together\ every\ntime\ \[\[`\[lcomp\]`\]\ is\ called,\ so\ don't\ put\ \[\[`\[lcomp\]`\]\ in\ a\ loop.\n(This\ is\ topical\ because\ it's\ an\ attempt\ to\ find\ alternatives\ to\ `for`\ for\n(This\ is\ topical\ because\ it's\ an\ attempt\ to\ find\ alternatives\ to\ \[\[`for`\]\ for\nanother\ idea:\ ''dictionary\ comprehensions!'')\n\n\[NEM\]\ 2006-06-12:\ List\ comprehensions\ can\ be\ generalised\ to\ allow\ queries\ over\na\ range\ of\ different\ data\ structures.\ At\ the\ end\ of\ this\ road\ are\ things\ like\n\[http://www-db.in.tum.de/~grust/files/monad-comprehensions.pdf%|%monad\ncomprehensions\ (Torsten\ Grust)\]\ and\ Microsoft's\ new\ \[LINQ\]\ framework\ for\ \[.NET\].\n\n----\n\n\[Sarnold\]\ finds\ this\ quick\ enough\ :\n\n======\nproc\ map\ \{cmd\ mylist\}\ \{\n\ \ \ \ set\ r\ \"\"\n\ \ \ \ foreach\ e\ \$mylist\ \{lappend\ r\ \[\$cmd\ \$e\]\}\n\ \ \ \ set\ r\n\}\nproc\ negate-even\ \{x\}\ \{expr\ \{\$x%2==0\ ?\ -\$x\ :\ \$x\}\}\nmap\ negate-even\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\}\n======\n\nWith\ `\[lambda\]`,\ it\ could\ be\ even\ simpler.\nWith\ \[\[`\[lambda\]`\],\ it\ could\ be\ even\ simpler.\n\[RS\]:\ `\[lmap\]`\ is\ a\ lambda/map\ compromise\ pretty\ much\ in\ Tcl's\n\[RS\]:\ \[\[`\[lmap\]`\]\ is\ a\ lambda/map\ compromise\ pretty\ much\ in\ Tcl's\n\[\[`\[foreach\]`\]\ spirit.\n----\n\n\[wdb\]:\ In\ \[Python\]\ there\ is\ only\ a\ `\[foreach\]`\ equivalent,\ and\ for-loops\ are\n\[wdb\]:\ In\ \[Python\]\ there\ is\ only\ a\ \[\[`\[foreach\]`\]\ equivalent,\ and\ for-loops\ are\n\nIn\ Tcl,\ you\ can\ define\ a\ proc\ range\ as\ follows:\n\n======\nproc\ range\ \{from\ \{to\ \"\"\}\ \{step\ 1\}\}\ \{\n\ \ \ \ if\ \{\$to\ eq\ \"\"\}\ then\ \{\n\ \ \ \ \ \ \ \ set\ to\ \$from\n\ \ \ \ \ \ \ \ set\ from\ 0\n\ \ \ \ \}\n\ \ \ \ set\ result\ \{\}\n\ \ \ \ for\ \{set\ x\ \$from\}\ \{\$x\ <\ \$to\}\ \{set\ x\ \[expr\ \{\$x\ +\ \$step\}\]\}\ \{\n\ \ \ \ \ \ \ \ lappend\ result\ \$x\n\ \ \ \ \}\n\ \ \ \ set\ result\n\}\n======\n\nNow,\ having\ this\ function,\ you\ can\ say:\n\n======\nforeach\ i\ \[range\ 4\ 11\]\ \{puts\ \$i\}\n======\n\nwhich\ makes\ your\ code\ shorter\ (but\ not\ faster).\n\n\[Lars\ H\]:\ And\ places\ you\ at\ the\ mercy\ of\ the\ endpoint\ conventions\ used\ —\ which\nare\ not\ the\ same\ in\ this\ '''range'''\ as\ in\ the\ other\ '''range'''\ on\ this\ page.\n\[Murphy\]\ strikes\ again!\n\n\n\n**\ `for`\ vs\ `\[while\]`\ **\n**\ \[\[`for`\]\ vs\ \[\[`\[while\]`\]\ **\nIn\ some\ languages,\ the\ range\ of\ a\ '''for'''\ loop\ is\ determined\ at\ the\ start\ of\nthe\ loop,\ and\ unbounded\ loops\ must\ rather\ be\ coded\ using\ '''while'''.\ \[Tcl\]\ is\n''not''\ one\ of\ those\ languages\ (because\ of\ \[C\]\ heritage),\ so\ '''for'''\ is\npreferable\ to\ '''while'''\ whenever\ there\ is\ a\ loop\ variable.\n\nOne\ case\ where\ this\ happens\ is\ a\ loop\ over\ the\ elements\ of\ a\ list\ (queue),\nwhere\ processing\ one\ element\ may\ cause\ further\ elements\ to\ be\ appended\ to\ the\nlist:\n\n======\nproc\ graph_component\ \{graph\ v\}\ \{\n\ \ \ \ set\ queue\ \[list\ \$v\]\n\ \ \ \ for\ \{set\ n\ 0\}\ \{\$n\ <\ \[llength\ \$queue\]\}\ \{incr\ n\}\ \{\n\ \ \ \ \ \ \ \ set\ v\ \[lindex\ \$queue\ \$n\]\n\ \ \ \ \ \ \ \ if\ \{\[info\ exists\ seen(\$v)\]\}\ then\ \{continue\}\n\ \ \ \ \ \ \ \ set\ seen(\$v)\ \{\}\n\ \ \ \ \ \ \ \ lappend\ queue\ \{*\}\[dict\ get\ \$graph\ \$v\]\n\ \ \ \ \}\n\ \ \ \ return\ \[array\ names\ seen\]\n\}\n======\n\n''\[graph\]''\ here\ is\ assumed\ to\ be\ a\ dictionary\ mapping\ vertices\ to\ their\ lists\nof\ neighbours.\ ''v''\ is\ the\ vertex\ whose\ component\ one\ wishes\ to\ compute.\n\nThe\ corresponding\ loop\ with\ `\[while\]`\ is\ less\ clear:\nThe\ corresponding\ loop\ with\ \[\[`\[while\]`\]\ is\ less\ clear:\n======\nproc\ graph_component\ \{graph\ v\}\ \{\n\ \ \ \ set\ queue\ \[list\ \$v\]\n\ \ \ \ set\ n\ 0\n\ \ \ \ while\ \{\$n\ <\ \[llength\ \$queue\]\}\ \{\n\ \ \ \ \ \ \ \ set\ v\ \[lindex\ \$queue\ \$n\]\n\ \ \ \ \ \ \ \ incr\ n\n\ \ \ \ \ \ \ \ if\ \{\[info\ exists\ seen(\$v)\]\}\ then\ \{continue\}\n\ \ \ \ \ \ \ \ set\ seen(\$v)\ \{\}\n\ \ \ \ \ \ \ \ lappend\ queue\ \{*\}\[dict\ get\ \$graph\ \$v\]\n\ \ \ \ \}\n\ \ \ \ return\ \[array\ names\ seen\]\n\}\n======\n\n`\[foreach\]`\ alone\ wouldn't\ work,\ because\ the\ ''queue''\ can\ grow.\ \ A\n\[\[`\[foreach\]`\]\ alone\ wouldn't\ work,\ because\ the\ ''queue''\ can\ grow.\ \ A\n\[\[`\[while\]`\]–\[\[`\[foreach\]`\]\ combination\ is\ possible,\ but\ less\ clear\ than\ the\nsimple\ \[\[`for`\]:\n======\nproc\ graph_component\ \{graph\ v\}\ \{\n\ \ \ \ set\ queue\ \[list\ \$v\]\n\ \ \ \ while\ \{\[llength\ \$queue\]\}\ \{\n\ \ \ \ \ \ \ \ set\ next\ \{\}\n\ \ \ \ \ \ \ \ foreach\ v\ \$queue\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[info\ exists\ seen(\$v)\]\}\ then\ \{continue\}\n\ \ \ \ \ \ \ \ \ \ \ \ set\ seen(\$v)\ \{\}\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ next\ \{*\}\[dict\ get\ \$graph\ \$v\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ set\ queue\ \$next\n\ \ \ \ \}\n\ \ \ \ return\ \[array\ names\ seen\]\n\}\n======\n\n\n\n**\ Dynamic\ Expressions\ **\n\nThe\ bracing\ of\ ''test''\ minimizes\ interpretation\ of\ the\ value\ by\ Tcl,\ before\npassing\ the\ value\ to\ `\[expr\]`.\ \ Tcl\ interpretation\ can\ be\ used,\ though\ to\npassing\ the\ value\ to\ \[\[`\[expr\]`\].\ \ Tcl\ interpretation\ can\ be\ used,\ though\ to\naccomplish\ that\ is\ to\ call\ '''\[expr\]'''\ from\ within\ the\ expression\ itself:\n\n======\nset\ op\ <\nfor\ \{set\ x\ 0\}\ \{\[expr\ \$x\ \$op\ 10\]\}\ \{incr\ x\}\ \{puts\ \"x\ is\ \$x\"\}\ \;#RS\n======\n\nNote\ that\ not\ bracing\ the\ \[expr\]\ expression\ ''will''\ mean\ there\ are\ two\nsubstitution\ rounds.\ This\ can\ lead\ to\ problems\ if\ some\ substituted\ value\ is\ not\na\ simple\ number.\n\nAlternatively,\ use\ quotes\ and\ backslashes:\n\n======\nset\ op\ <\nfor\ \{set\ x\ 0\}\ \"\\\$x\ \$op\ 10\"\ \{incr\ x\}\ \{puts\ \"x\ is\ \$x\"\}\n======\n\nThis\ substitutes\ ''op''\ before\ calling\ \[for\],\ but\ ''x''\ only\ when\ the\nexpression\ is\ evaluated.\ This\ technique\ makes\ it\ easier\ to\ handle\ complex\nsubstituted\ values,\ but\ the\ need\ to\ escape\ all\ `\$`\ signs\ can\ be\ a\ burden\ in\ncomplex\ expressions.\n\n\n\n**\ Making\ Use\ of\ all\ the\ Arguments\ to\ `for`\ **\n**\ Making\ Use\ of\ all\ the\ Arguments\ to\ \[\[`for`\]\ **\n\[lexfiend\]\ 2006-06-12:\ \ While\ most\ people\ think\ of\ `for`\ in\ terms\ of\ C-style\n\[lexfiend\]\ 2006-Jun-12:\ \ While\ most\ people\ think\ of\ \[for\]\ in\ terms\ of\ C-style\n\[https://groups.google.com/d/msg/comp.lang.tcl/GHxR1W_p7-Y/s1Q_h2BzDUwJ%|%how\nto\ gets\ with\ an\ arbitrary\ \"newline\"\ character\],\ \[comp.lang.tcl\],\ 2006-06-11,\nthat\ ''start'',\ ''test''\ and\ ''next''\ could\ do\ many\ other\ things\ too.\ \ The\ code\nfragment\ in\ question:\n\n======\nfor\ \{fconfigure\ \$pipe\ -eofchar\ \\u0000\}\ \{\n\ \ \ \ \[string\ length\ \[set\ record\ \[read\ \$pipe\]\]\]\n\}\ \{seek\ \$pipe\ 1\ current\}\ \{\n\ \ \ \ #\ process\ \$record\ here\n\}\n======\n\nis\ an\ impressively\ succinct\ rendition\ of\ the\ more\ typical:\n\n======\nfconfigure\ \$pipe\ -eofchar\ \\u0000\nwhile\ 1\ \{\n\ \ \ \ #\ Read\ up\ to\ the\ next\ eof\ char,\ as\ configured\n\ \ \ \ set\ record\ \[read\ \$pipe\]\n\ \ \ \ if\ \{\[string\ length\ \$record\]\}\ \{\n\ \ \ \ \ \ \ \ #\ process\ \$record\ here\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ break\n\ \ \ \ \}\n\ \ \ \ #\ skip\ over\ the\ eof\ char\n\ \ \ \ seek\ \$pipe\ 1\ current\n\}\n======\n\nOf\ course,\ the\ downside\ to\ using\ this\ sort\ of\ reductionist\ construct\ is\ that\ it\ncan\ sometimes\ be\ hard\ to\ be\ sure\ your\ logic\ is\ correct.\ 8-)\n\n\[RS\]:\ The\ flexibility\ of\ the\ three\ first\ arguments\ to\ for\ was\ directly\ninherited\ from\ \[C\],\ where\ you\ have\ the\ same\ liberties.\n\n\[Lars\ H\]:\ Actually,\ Tcl\ gives\ you\ ''greater''\ liberties\ than\ C\ here,\ because\ in\nC\ the\ ''start''\ and\ ''next''\ are\ restricted\ to\ being\ expressions,\ and\nexpressions\ in\ C\ cannot\ do\ any\ flow\ control.\ \ In\ a\ C\ expression,\ there's\ no\ way,\ for\ example,\ to\ `\[return\]`\ or\ even\ throw\ an\ `\[error\]`,\ whereas\ Tcl\ lets\ you\ do\nexpressions\ in\ C\ cannot\ do\ any\ flow\ control\ —\ there's\ no\ way\ to\ e.g.\ \[return\]\nor\ even\ throw\ an\ \[error\]\ from\ within\ a\ C\ expression\ —\ whereas\ Tcl\ lets\ you\ do\n\n\[aspect\]:\ While\ the\ `for`\ code\ above\ suffers\ in\ readability,\ it's\ heading\n\[aspect\]:\ While\ the\ \[\[`\[for\]`\]\ code\ above\ suffers\ in\ readability,\ it's\ heading\ndown\ a\ useful\ path.\ \[Lisp\]ers\ would\ tend\ to\ look\ for\ an\ underlying\ abstraction\n\n======\nproc\ with-records\ \{eofchar\ \$_record\ body\}\ \{\n\ \ \ \ upvar\ 1\ \$_record\ record\n\ \ \ \ set\ _eofchar\ \[fconfigure\ \$pipe\ -eofchar\]\n\ \ \ \ for\ \{fconfigure\ \$pipe\ -eofchar\ \$eofchar\}\ \{\n\ \ \ \ \ \ \ \ \[string\ length\ \[set\ record\ \[read\ \$pipe\]\]\]\n\ \ \ \ \}\ \{seek\ \$pipe\ 1\ current\}\ \{\n\ \ \ \ \ \ \ \ uplevel\ 1\ \$body\n\ \ \ \ \}\n\ \ \ \ fconfigure\ \$pipe\ -eofchar\ \$_eofchar\n\}\n======\n\nIn\ writing\ this\ construct,\ the\ need\ to\ reset\ `-eofchar`\ at\ the\ end\ of\ the\ look\nwas\ exposed\ and\ easily\ addressed.\ Also\ I'd\ tend\ to\ use\ the\ default\ name\ `\$_`\nfor\ the\ record\ instead\ of\ having\ to\ explicitly\ provide\ it,\ but\ that's\ a\ matter\nof\ taste,\ as\ is\ the\ name\ of\ the\ procedure,\ which\ I'm\ not\ entirely\ happy\ with.\nof\ taste.\ \ As\ is\ the\ name\ of\ the\ procedure,\ which\ I'm\ not\ entirely\ happy\ with.\nBut\ the\ point\ is\ that\ making\ \[New\ Control\ Structures\]\ is\ easy:\ you\ don't\ have\nto\ be\ shoehorn\ your\ problem\ into\ \[\[`\[for\]`\],\ \[\[`\[foreach\]`\]\ and\ \[\[`\[while\]`\]\n\n\n\n**\ Tips\ and\ Tricks\ on\ `for`\ **\n**\ Tips\ and\ Tricks\ on\ \[\[`\[for\]`\]\ **\nA\ poster\ to\ \[comp.lang.tcl\]\ mentioned\ the\ following\ problem.\ Some\ code\ was\ set\nup\ like\ this:\n\n======\nset\ size\ \[getresult\ from\ operation\]\nfor\ \{set\ i\ 0\}\ \{\$i<\$size\}\ \{incr\ i\}\ \{\n\ \ \ \ set\ workingarray(\$i)\ 0\n\}\n======\n\nHowever,\ due\ to\ a\ mistake,\ the\ output\ from\ `getresult`\ changed\ at\ one\ point\nHowever,\ due\ to\ a\ mistake,\ the\ output\ from\ \[\[getresult\]\ changed\ at\ one\ point\nfrom\ being\ a\ number\ to\ being\ a\ string.\ \ Rather\ than\ causing\ for\ to\ raise\ an\nerror,\ the\ bug\ caused\ the\ for\ loop\ to\ loop\ thousands\ of\ time,\ until\ in\ the\n\nWhile\ \n\n======\nexpr\ \$i\ <\ \$size\n======\n\nwould\ raise\ an\ error\n\n======\nexpr\ \{\$i<\$size\}\n======\n\n,\ as\ well\ as\ the\ use\ within\ the\ `for`\ only\ returns\ a\ 1,\ causing\ the\ loop\ to\ run\nas\ well\ as\ the\ use\ within\ the\ for\ only\ returns\ a\ 1,\ causing\ the\ loop\ to\ run\n\nTest\ your\ variables\ to\ ensure\ they\ actually\ have\ the\ type\ of\ value\ you\ expect,\nafter\ getting\ values\ from\ a\ user\ or\ external\ source.\n\nA\ quick\ way\ to\ \[assert\]\ that\ a\ value\ is\ an\ integer\ is\ to\ `\[incr\]`\ it\ by\ `0`,\ like\nA\ quick\ way\ to\ \[assert\]\ that\ a\ value\ is\ an\ integer\ is\ to\ \[incr\]\ it\ by\ 0,\ like\n\n======\nset\ size\ \[getresult\ from\ operation\]\nincr\ size\ 0\nfor\ \{set\ i\ 0\}\ \{\$i<\$size\}\ \{incr\ i\}\ \{\n\ \ \ \ set\ workingarray(\$i)\ 0\n\}\n======\n\n\n<<categories>>\ Arts\ and\ Crafts\ of\ Tcl-Tk\ Programming\ |\ Tcl\ syntax\ help\ |\ Command\ |\ Control\ Structure regexp2} CALL {my render for '''\[http://www.tcl.tk/man/tcl/TclCmd/for.htm%|%for\]''',\ a\ \[Tcl\ Commands%|%built-in\]\ \[Tcl\]\ command,\ provides\ an\ iterative\ loop\ construct.\n\n\n\n**\ See\ Also\ **\n\n\ \ \ \[break\]:\ \ \ \n\n\ \ \ \[continue\]:\ \ \ \n\n\ \ \ \[expr\]:\ \ \ \n\n\ \ \ \[foreach\]:\ \ \ \n\n\ \ \ \[if\]:\ \ \ \n\n\ \ \ \[while\]:\ \ \ \n\n\ \ \ \[fold\]\ /\ \[map\]\ /\ \[zip\]\ etc:\ \ \ \n\n\ \ \ \[for\ in%|%for\ ...\ in\]:\ \ \ \n\n\n\n**\ Synopsis\ **\n\n'''for'''\ ''start\ test\ next\ body''\n\n\n\n**\ Documentation\ **\n\n\ \ \ \[http://www.tcl.tk/man/tcl/TclCmd/for.htm%|%official\ reference\]:\ \ \ \n\n\n\n**\ Description\ **\n\n'''For'''\ is\ a\ looping\ command,\ similar\ in\ structure\ to\ the\ C\ '''for'''\nstatement.\ \ The\ ''start'',\ ''next'',\ and\ ''body''\ arguments\ are\ scripts\nstatement.\ \ The\ ''start'',\ ''next'',\ and\ ''body''\ arguments\ must\ be\ Tcl\ command\nstrings,\ and\ ''test''\ is\ an\ \[\[`\[expr\]`\]\ argument.\ \[\[`for`\]\ first\ invokes\ the\nTcl\ interpreter\ to\ execute\ ''start''.\ \ Then\ it\ iteratively\ evaluates\ ''test''\nas\ an\ expression,\ and\ if\ the\ result\ is\ non-zero,\ then\ evaluates\ ''body''\ as\ a\nTcl\ script.\ \ Finally,\ it\ evaluates\ ''next''\ as\ a\ Tcl\ script,\ and\ then\ repeats\nthe\ loop.\n`\[continue\]`\ and\ `\[break\]`\ function\ in\ a\ manner\ similar\ to\ the\ corresponding\n\[\[`for`\]\ terminates\ when\ ''test''\ evaluates\ to\ `0`.\ \ If\ a\ \[\[`\[continue\]`\]\ is\ninvoked\ within\ ''body''\ then\ any\ remaining\ commands\ in\ the\ current\ evalutaion\nof\ ''body''\ are\ skipped,\ \ ''next''\ is\ evaluated\ as\ a\ Tcl\ script,\ ''test''\ is\nagain\ evaluated,\ and\ so\ on.\ \ If\ \[\[`\[break\]`\]\ is\ invoked\ within\ ''body''\ or\n''next'',\ \[\[`for`\]\ returns\ immediately.\ \ \[\[`\[break\]`\]\ and\ \[\[`\[continue\]`\]\nfunction\ in\ a\ manner\ similar\ to\ the\ corresponding\ statements\ in\ C.\ \[\[`for`\]\nreturns\ an\ empty\ string.\ \n`for`\ returns\ an\ empty\ string.\ \n''test''\ should\ almost\ always\ be\ enclosed\ in\ braces.\ \ If\ not,\ variable\nsubstitutions\ will\ be\ made\ by\ Tcl\ before\ it\ calls\ \[\[`for`\],\ causing\ \[\[`for`\]\ to\nsee\ the\ value\ intead\ of\ the\ variable,\ and\ preventing\ it\ from\ detecting\ changes\nmade\ to\ the\ variable\ in\ ''body''.\ \ This\ is\ likely\ to\ result\ in\ an\ infinite\nloop,\ and\ to\ the\ possibility\ of\ unintended\ effects\ from\ \[double\ substitution\].\nIf\ ''test''\ is\ enclosed\ in\ braces,\ Tcl\ does\ not\ perform\ substitutions\ on\ it\ and\ntherefore\ does\ not\ step\ on\ the\ toes\ of\ \[\[`if`\]\ as\ it\ uses\ \[\[`\[expr\]`\]\ to\nperfrom\ its\ own\ substitutions.\ \ For\ an\ example,\ try\ the\ following\ script\ with\nand\ without\ the\ braces\ around\ `\$x<10`:\ \n''test''\ should\ almost\ always\ be\ enclosed\ in\ braces.\ \ Otherwise,\ substitutions\nfor\ \{set\ x\ 0\}\ \{\$x<10\}\ \{incr\ x\}\ \{\n\ \ \ \ puts\ \"x\ is\ \$x\"\n\}\n======\n\nSee\ also:\ \[TclHelp\]\n\n\n\n**\ `for`\ vs\ `\[foreach\]`\ **\n**\ \[\[`\[for\]`\]\ vs\ \[\[`\[foreach\]`\]\ **\n`\[foreach\]`\ is\ generally\ better\ style\ for\ non-numeric\ looping.\ Those\n\[\[`\[foreach\]`\]\ is\ generally\ better\ style\ for\ non-numeric\ looping.\ Those\nbecause\ they\ think\ of\ an\ indexed\ array\ where\ a\ Tcl\ programmer\ writes:\n\n======\nset\ color_list\ \"red\ blue\ umber\ mauve\"\nforeach\ color\ \$color_list\ \{...\}\n======\n\nIn\ some\ situations,\ using\ `\[foreach\]`\ with\ a\ fixed\ list\ is\ more\ convenient\nIn\ some\ situations,\ using\ \[\[`\[foreach\]`\]\ with\ a\ fixed\ list\ is\ more\ convenient\nthan\ \[\[`for`\],\ even\ if\ the\ list\ is\ numeric.\ \ Compare:\n======\nforeach\ i\ \{1\ 2\ 3\ 4\ 5\}\ \{...\nfor\ \{set\ i\ 1\}\ \{\$i\ <=\ 5\}\ \{incr\ i\}\ \{...\n======\n\n----\n\nSome\ find\ the\ idea\ of\ using\ `\[foreach\]`\ on\ a\ range\ of\ integers\ so\ nice\ that\nSome\ find\ the\ idea\ of\ using\ \[\[`\[foreach\]`\]\ on\ a\ range\ of\ integers\ so\ nice\ that\nthey\ pour\ some\ sugar\ over\ \[\[`for`\]:\n======\nproc\ range\ \{from\ to:\ to\}\ \{\n\ \ \ \ set\ res\ \[list\]\n\ \ \ \ for\ \{set\ i\ \$from\}\ \{\$i<=\$to\}\ \{incr\ i\}\ \{lappend\ res\ \$i\}\n\ \ \ \ set\ res\n\}\nforeach\ i\ \[range\ 1\ ..\ 5\]\ \{...\n======\n\nThis\ is,\ however,\ slower\ than\ `for`.\nThis\ is,\ however,\ slower\ than\ \[\[`\[for\]`\].\n----\n\nThe\ main\ difference\ between\ `for`\ and\ `\[foreach\]`\ when\ iterating\ over\ a\nThe\ main\ difference\ between\ \[\[`for`\]\ and\ \[\[`\[foreach\]`\]\ when\ iterating\ over\ a\nlist\ is\ that\ with\ \[\[`for`\]\ the\ index\ into\ the\ list\ is\ available,\ whereas\ with\n\[\[`\[foreach\]`\],\ it\ is\ not.\ \ \[\[`\[foreach\]`\]\ can,\ however,\ be\ preferable\ even\ if\nthe\ list\ index\ is\ needed.\ \ What\ would\ traditionally\ be\ coded\ as\n======\nfor\ \{set\ index\ 0\}\ \{\$index\ <\ \[llength\ \$list\]\}\ \{incr\ index\}\ \{\n\ \ \ \ set\ item\ \[lindex\ \$list\ \$index\]\n\ \ \ \ #\ Now\ do\ something\ using\ both\ \$index\ and\ \$item\n\ \ \ \ ...\n\}\n======\n\nis\ actually\ faster\ when\ written\ as\ the\ following\ `\[foreach\]`:\nis\ actually\ faster\ when\ written\ as\ the\ following\ \[\[`\[foreach\]`\]:\n======\nset\ index\ -1\nforeach\ item\ \$list\ \{\n\ \ \ \ incr\ index\n\ \ \ \ \ \ \ \ incr\ index\n\ \ \ \ ...\n\}\n======\n\nIn\ order\ for\ `\[continue\]`\ to\ do\ the\ right\ thing,\ `\[incr\]\ index`\ comes\ first\ in\nThe\ reason\ to\ \[\[`\[incr\]`\]\ ''index''\ first\ in\ the\ loop\ body\ is\ that\ this\ makes\n\[\[`\[continue\]`\]\ do\ the\ right\ thing.\n----\ \n\n\[AMG\]:\ Sometimes\ I\ need\ to\ chew\ through\ a\ list\ and\ conditionally\ edit,\ replace,\nor\ remove\ elements.\ \ I\ can\ easily\ read\ \"copies\"\ of\ each\ element\ in\ the\ list\nusing\ `\[foreach\]`,\ but\ when\ the\ condition\ triggers\ I\ need\ the\ list\ index\nusing\ \[\[`\[foreach\]`\]\],\ but\ when\ the\ condition\ triggers\ I\ need\ the\ list\ index\nfor\ \[\[`\[lreplace\]`\],\ \[\[`\[lset\]`\],\ \[\[`\[linsert\]`\],\ and\ the\ like.\ \ What's\ the\n\nOne\ option:\n\n======\nset\ list\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\}\nset\ index\ -1\nforeach\ elem\ \$list\ \{\n\ \ \ \ incr\ index\n\ \ \ \ if\ \{\$elem\ %\ 2\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ lset\ list\ \$index\ \[expr\ \{-\$elem\}\]\n\ \ \ \ \}\n\}\n======\n\nAnother\ option:\n\n======\nset\ list\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\}\nfor\ \{set\ index\ 0\}\ \{\$index\ <\ \[llength\ \$list\]\}\ \{incr\ index\}\ \{\n\ \ \ \ set\ elem\ \[lindex\ \$list\ \$index\]\n\ \ \ \ if\ \{\$elem\ %\ 2\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ lset\ list\ \$index\ \[expr\ \{-\$elem\}\]\n\ \ \ \ \}\n\}\n======\n\nWhich\ is\ preferred?\ \ Here's\ another\ option.\n\n======\nset\ list\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\}\nset\ result\ \[list\]\nforeach\ elem\ \$list\ \{\n\ \ \ \ if\ \{\$elem\ %\ 2\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ lappend\ result\ \[expr\ \{-\$elem\}\]\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ lappend\ result\ \$elem\n\ \ \ \ \}\n\}\nset\ list\ \$result\n======\n\nBetter\ still\ would\ be\ a\ list\ comprehension\ (e.g.,\ `\[lcomp\]`),\ but\ to\ me\ it\nBetter\ still\ would\ be\ a\ list\ comprehension\ (e.g.,\ \[\[`\[lcomp\]`\]),\ but\ to\ me\ it\n\n\[Lars\ H\]:\ Good\ question\;\ I\ often\ find\ myself\ wondering\ the\ same\ thing.\ I\nsuspect\ that\ rebuilding\ the\ list\ is\ on\ the\ whole\ the\ best\ approach,\ when\npossible\ (I\ think\ dragging\ the\ index\ around\ is\ sometimes\ unavoidable).\ An\ nice\nthing\ about\ the\ rebuild\ method\ is\ that\ it\ allows\ for\ more\ functional\ ways\ of\nwriting\ the\ body\;\ in\ this\ case\ the\ extreme\ is\ probably\n\n======\nset\ list\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\}\nset\ result\ \[list\]\nforeach\ elem\ \$list\ \{\n\ \ \ \ lappend\ result\ \[expr\ \{\n\ \ \ \ \ \ \ \ \$elem\ %\ 2\ ==\ 0\ ?\ -\$elem\ :\ \$elem\n\ \ \ \ \}\]\n\}\nset\ list\ \$result\n======\n\n\[AMG\]:\ If\ your\ code\ is\ functional,\ does\ that\ mean\ mine\ is\ dysfunctional?\ :^)\nSeriously,\ we\ should\ look\ into\ list\ comprehensions\ a\ bit\ more.\ \ Just\ how\ much\ndo\ they\ cost,\ when\ implemented\ in\ Tcl\ or\ C?\ \ Can\ something\ be\ done\ in\ C\ to\nallow\ for\ a\ better\ Tcl\ implementation?\ \ How\ do\ list\ comprehensions\ compare\ to\nwriting\ the\ equivalent\ `for`/`\[foreach\]`\ commands?\ \ Which\ is\ more\ readable\nwriting\ the\ equivalent\ \[\['''for'''\]\]s/\[\[\[foreach\]\]\]es?\ \ Which\ is\ more\ readable\n\nWith\ `\[lcomp\]`,\ the\ above\ is\ written:\nWith\ \[\[`\[lcomp\]`\],\ the\ above\ is\ written:\n======\nset\ list\ \[lcomp\ \{\[expr\ \{\$x\ *\ -1\ **\ (1\ -\ \$x\ %\ 2)\}\]\}\ x\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\}\]\n======\n\nYeah,\ maybe\ that\ exponentiation\ is\ going\ overboard,\ but\ I\ couldn't\ help\ myself.\n:^)\n\n\[Lars\ H\]:\ If\ you\ rewrite\ that\ expression\ using\ the\ ?:\ operation,\ you'll\ see\nthat\ my\ code\ was\ just\ an\ unrolled\ version\ of\ your\ `\[lcomp\]`.\ The\ last\ three\nthat\ my\ code\ was\ just\ an\ unrolled\ version\ of\ your\ \[\[`\[lcomp\]`\].\ The\ last\ three\nfunctional\ style.\n\n`\[lcomp\]`\ can\ be\ modified\ to\ `\[eval\]`\ its\ first\ argument,\ perhaps\ in\ a\n\[\[`\[lcomp\]`\]\ can\ be\ modified\ to\ \[\[`\[eval\]`\]\ its\ first\ argument,\ perhaps\ in\ a\nchild\ interpreter\ with\ an\ \[\['''emit'''\]\ command.\ \ That\ would\ allow\ the\ above\ to\n\n======\nset\ list\ \[lcomp\ \{\n\ \ \ \ if\ \{\$x\ %\ 2\ ==\ 0\}\ \{\n\ \ \ \ \ \ \ \ emit\ \[expr\ \{-\$x\}\]\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ emit\ \$x\n\ \ \ \ \}\n\}\ x\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\}\]\n======\n\nPlus,\ if\ '''`emit`'''\ can\ take\ multiple\ arguments\ and/or\ can\ be\ called\nPlus,\ if\ \[\['''emit'''\]\ can\ take\ multiple\ arguments\ and/or\ can\ be\ called\nnumber\ (including\ zero)\ of\ output\ elements.\ \ Hmm.\n\nHey,\ joyous\ idea.\ \ The\ first\ argument\ gets\ passed\ unmodified\ to\ `\[eval\]`\nHey,\ joyous\ idea.\ \ The\ first\ argument\ gets\ passed\ unmodified\ to\ \[\[`\[eval\]`\]\]\n(or\ \[\[`\[interp\ eval\]`\]\]),\ which\ should\ (??)\ allow\ Tcl\ to\ bytecode\ compile\ it.\nBonus!\ \ But\ the\ nests\ of\ \[\[`\[foreach\]`\]es\ would\ still\ be\ pieced\ together\ every\ntime\ \[\[`\[lcomp\]`\]\ is\ called,\ so\ don't\ put\ \[\[`\[lcomp\]`\]\ in\ a\ loop.\n(This\ is\ topical\ because\ it's\ an\ attempt\ to\ find\ alternatives\ to\ `for`\ for\n(This\ is\ topical\ because\ it's\ an\ attempt\ to\ find\ alternatives\ to\ \[\[`for`\]\ for\nanother\ idea:\ ''dictionary\ comprehensions!'')\n\n\[NEM\]\ 2006-06-12:\ List\ comprehensions\ can\ be\ generalised\ to\ allow\ queries\ over\na\ range\ of\ different\ data\ structures.\ At\ the\ end\ of\ this\ road\ are\ things\ like\n\[http://www-db.in.tum.de/~grust/files/monad-comprehensions.pdf%|%monad\ncomprehensions\ (Torsten\ Grust)\]\ and\ Microsoft's\ new\ \[LINQ\]\ framework\ for\ \[.NET\].\n\n----\n\n\[Sarnold\]\ finds\ this\ quick\ enough\ :\n\n======\nproc\ map\ \{cmd\ mylist\}\ \{\n\ \ \ \ set\ r\ \"\"\n\ \ \ \ foreach\ e\ \$mylist\ \{lappend\ r\ \[\$cmd\ \$e\]\}\n\ \ \ \ set\ r\n\}\nproc\ negate-even\ \{x\}\ \{expr\ \{\$x%2==0\ ?\ -\$x\ :\ \$x\}\}\nmap\ negate-even\ \{0\ 1\ 2\ 3\ 4\ 5\ 6\}\n======\n\nWith\ `\[lambda\]`,\ it\ could\ be\ even\ simpler.\nWith\ \[\[`\[lambda\]`\],\ it\ could\ be\ even\ simpler.\n\[RS\]:\ `\[lmap\]`\ is\ a\ lambda/map\ compromise\ pretty\ much\ in\ Tcl's\n\[RS\]:\ \[\[`\[lmap\]`\]\ is\ a\ lambda/map\ compromise\ pretty\ much\ in\ Tcl's\n\[\[`\[foreach\]`\]\ spirit.\n----\n\n\[wdb\]:\ In\ \[Python\]\ there\ is\ only\ a\ `\[foreach\]`\ equivalent,\ and\ for-loops\ are\n\[wdb\]:\ In\ \[Python\]\ there\ is\ only\ a\ \[\[`\[foreach\]`\]\ equivalent,\ and\ for-loops\ are\n\nIn\ Tcl,\ you\ can\ define\ a\ proc\ range\ as\ follows:\n\n======\nproc\ range\ \{from\ \{to\ \"\"\}\ \{step\ 1\}\}\ \{\n\ \ \ \ if\ \{\$to\ eq\ \"\"\}\ then\ \{\n\ \ \ \ \ \ \ \ set\ to\ \$from\n\ \ \ \ \ \ \ \ set\ from\ 0\n\ \ \ \ \}\n\ \ \ \ set\ result\ \{\}\n\ \ \ \ for\ \{set\ x\ \$from\}\ \{\$x\ <\ \$to\}\ \{set\ x\ \[expr\ \{\$x\ +\ \$step\}\]\}\ \{\n\ \ \ \ \ \ \ \ lappend\ result\ \$x\n\ \ \ \ \}\n\ \ \ \ set\ result\n\}\n======\n\nNow,\ having\ this\ function,\ you\ can\ say:\n\n======\nforeach\ i\ \[range\ 4\ 11\]\ \{puts\ \$i\}\n======\n\nwhich\ makes\ your\ code\ shorter\ (but\ not\ faster).\n\n\[Lars\ H\]:\ And\ places\ you\ at\ the\ mercy\ of\ the\ endpoint\ conventions\ used\ —\ which\nare\ not\ the\ same\ in\ this\ '''range'''\ as\ in\ the\ other\ '''range'''\ on\ this\ page.\n\[Murphy\]\ strikes\ again!\n\n\n\n**\ `for`\ vs\ `\[while\]`\ **\n**\ \[\[`for`\]\ vs\ \[\[`\[while\]`\]\ **\nIn\ some\ languages,\ the\ range\ of\ a\ '''for'''\ loop\ is\ determined\ at\ the\ start\ of\nthe\ loop,\ and\ unbounded\ loops\ must\ rather\ be\ coded\ using\ '''while'''.\ \[Tcl\]\ is\n''not''\ one\ of\ those\ languages\ (because\ of\ \[C\]\ heritage),\ so\ '''for'''\ is\npreferable\ to\ '''while'''\ whenever\ there\ is\ a\ loop\ variable.\n\nOne\ case\ where\ this\ happens\ is\ a\ loop\ over\ the\ elements\ of\ a\ list\ (queue),\nwhere\ processing\ one\ element\ may\ cause\ further\ elements\ to\ be\ appended\ to\ the\nlist:\n\n======\nproc\ graph_component\ \{graph\ v\}\ \{\n\ \ \ \ set\ queue\ \[list\ \$v\]\n\ \ \ \ for\ \{set\ n\ 0\}\ \{\$n\ <\ \[llength\ \$queue\]\}\ \{incr\ n\}\ \{\n\ \ \ \ \ \ \ \ set\ v\ \[lindex\ \$queue\ \$n\]\n\ \ \ \ \ \ \ \ if\ \{\[info\ exists\ seen(\$v)\]\}\ then\ \{continue\}\n\ \ \ \ \ \ \ \ set\ seen(\$v)\ \{\}\n\ \ \ \ \ \ \ \ lappend\ queue\ \{*\}\[dict\ get\ \$graph\ \$v\]\n\ \ \ \ \}\n\ \ \ \ return\ \[array\ names\ seen\]\n\}\n======\n\n''\[graph\]''\ here\ is\ assumed\ to\ be\ a\ dictionary\ mapping\ vertices\ to\ their\ lists\nof\ neighbours.\ ''v''\ is\ the\ vertex\ whose\ component\ one\ wishes\ to\ compute.\n\nThe\ corresponding\ loop\ with\ `\[while\]`\ is\ less\ clear:\nThe\ corresponding\ loop\ with\ \[\[`\[while\]`\]\ is\ less\ clear:\n======\nproc\ graph_component\ \{graph\ v\}\ \{\n\ \ \ \ set\ queue\ \[list\ \$v\]\n\ \ \ \ set\ n\ 0\n\ \ \ \ while\ \{\$n\ <\ \[llength\ \$queue\]\}\ \{\n\ \ \ \ \ \ \ \ set\ v\ \[lindex\ \$queue\ \$n\]\n\ \ \ \ \ \ \ \ incr\ n\n\ \ \ \ \ \ \ \ if\ \{\[info\ exists\ seen(\$v)\]\}\ then\ \{continue\}\n\ \ \ \ \ \ \ \ set\ seen(\$v)\ \{\}\n\ \ \ \ \ \ \ \ lappend\ queue\ \{*\}\[dict\ get\ \$graph\ \$v\]\n\ \ \ \ \}\n\ \ \ \ return\ \[array\ names\ seen\]\n\}\n======\n\n`\[foreach\]`\ alone\ wouldn't\ work,\ because\ the\ ''queue''\ can\ grow.\ \ A\n\[\[`\[foreach\]`\]\ alone\ wouldn't\ work,\ because\ the\ ''queue''\ can\ grow.\ \ A\n\[\[`\[while\]`\]–\[\[`\[foreach\]`\]\ combination\ is\ possible,\ but\ less\ clear\ than\ the\nsimple\ \[\[`for`\]:\n======\nproc\ graph_component\ \{graph\ v\}\ \{\n\ \ \ \ set\ queue\ \[list\ \$v\]\n\ \ \ \ while\ \{\[llength\ \$queue\]\}\ \{\n\ \ \ \ \ \ \ \ set\ next\ \{\}\n\ \ \ \ \ \ \ \ foreach\ v\ \$queue\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[info\ exists\ seen(\$v)\]\}\ then\ \{continue\}\n\ \ \ \ \ \ \ \ \ \ \ \ set\ seen(\$v)\ \{\}\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ next\ \{*\}\[dict\ get\ \$graph\ \$v\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ set\ queue\ \$next\n\ \ \ \ \}\n\ \ \ \ return\ \[array\ names\ seen\]\n\}\n======\n\n\n\n**\ Dynamic\ Expressions\ **\n\nThe\ bracing\ of\ ''test''\ minimizes\ interpretation\ of\ the\ value\ by\ Tcl,\ before\npassing\ the\ value\ to\ `\[expr\]`.\ \ Tcl\ interpretation\ can\ be\ used,\ though\ to\npassing\ the\ value\ to\ \[\[`\[expr\]`\].\ \ Tcl\ interpretation\ can\ be\ used,\ though\ to\naccomplish\ that\ is\ to\ call\ '''\[expr\]'''\ from\ within\ the\ expression\ itself:\n\n======\nset\ op\ <\nfor\ \{set\ x\ 0\}\ \{\[expr\ \$x\ \$op\ 10\]\}\ \{incr\ x\}\ \{puts\ \"x\ is\ \$x\"\}\ \;#RS\n======\n\nNote\ that\ not\ bracing\ the\ \[expr\]\ expression\ ''will''\ mean\ there\ are\ two\nsubstitution\ rounds.\ This\ can\ lead\ to\ problems\ if\ some\ substituted\ value\ is\ not\na\ simple\ number.\n\nAlternatively,\ use\ quotes\ and\ backslashes:\n\n======\nset\ op\ <\nfor\ \{set\ x\ 0\}\ \"\\\$x\ \$op\ 10\"\ \{incr\ x\}\ \{puts\ \"x\ is\ \$x\"\}\n======\n\nThis\ substitutes\ ''op''\ before\ calling\ \[for\],\ but\ ''x''\ only\ when\ the\nexpression\ is\ evaluated.\ This\ technique\ makes\ it\ easier\ to\ handle\ complex\nsubstituted\ values,\ but\ the\ need\ to\ escape\ all\ `\$`\ signs\ can\ be\ a\ burden\ in\ncomplex\ expressions.\n\n\n\n**\ Making\ Use\ of\ all\ the\ Arguments\ to\ `for`\ **\n**\ Making\ Use\ of\ all\ the\ Arguments\ to\ \[\[`for`\]\ **\n\[lexfiend\]\ 2006-06-12:\ \ While\ most\ people\ think\ of\ `for`\ in\ terms\ of\ C-style\n\[lexfiend\]\ 2006-Jun-12:\ \ While\ most\ people\ think\ of\ \[for\]\ in\ terms\ of\ C-style\n\[https://groups.google.com/d/msg/comp.lang.tcl/GHxR1W_p7-Y/s1Q_h2BzDUwJ%|%how\nto\ gets\ with\ an\ arbitrary\ \"newline\"\ character\],\ \[comp.lang.tcl\],\ 2006-06-11,\nthat\ ''start'',\ ''test''\ and\ ''next''\ could\ do\ many\ other\ things\ too.\ \ The\ code\nfragment\ in\ question:\n\n======\nfor\ \{fconfigure\ \$pipe\ -eofchar\ \\u0000\}\ \{\n\ \ \ \ \[string\ length\ \[set\ record\ \[read\ \$pipe\]\]\]\n\}\ \{seek\ \$pipe\ 1\ current\}\ \{\n\ \ \ \ #\ process\ \$record\ here\n\}\n======\n\nis\ an\ impressively\ succinct\ rendition\ of\ the\ more\ typical:\n\n======\nfconfigure\ \$pipe\ -eofchar\ \\u0000\nwhile\ 1\ \{\n\ \ \ \ #\ Read\ up\ to\ the\ next\ eof\ char,\ as\ configured\n\ \ \ \ set\ record\ \[read\ \$pipe\]\n\ \ \ \ if\ \{\[string\ length\ \$record\]\}\ \{\n\ \ \ \ \ \ \ \ #\ process\ \$record\ here\n\ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ break\n\ \ \ \ \}\n\ \ \ \ #\ skip\ over\ the\ eof\ char\n\ \ \ \ seek\ \$pipe\ 1\ current\n\}\n======\n\nOf\ course,\ the\ downside\ to\ using\ this\ sort\ of\ reductionist\ construct\ is\ that\ it\ncan\ sometimes\ be\ hard\ to\ be\ sure\ your\ logic\ is\ correct.\ 8-)\n\n\[RS\]:\ The\ flexibility\ of\ the\ three\ first\ arguments\ to\ for\ was\ directly\ninherited\ from\ \[C\],\ where\ you\ have\ the\ same\ liberties.\n\n\[Lars\ H\]:\ Actually,\ Tcl\ gives\ you\ ''greater''\ liberties\ than\ C\ here,\ because\ in\nC\ the\ ''start''\ and\ ''next''\ are\ restricted\ to\ being\ expressions,\ and\nexpressions\ in\ C\ cannot\ do\ any\ flow\ control.\ \ In\ a\ C\ expression,\ there's\ no\ way,\ for\ example,\ to\ `\[return\]`\ or\ even\ throw\ an\ `\[error\]`,\ whereas\ Tcl\ lets\ you\ do\nexpressions\ in\ C\ cannot\ do\ any\ flow\ control\ —\ there's\ no\ way\ to\ e.g.\ \[return\]\nor\ even\ throw\ an\ \[error\]\ from\ within\ a\ C\ expression\ —\ whereas\ Tcl\ lets\ you\ do\n\n\[aspect\]:\ While\ the\ `for`\ code\ above\ suffers\ in\ readability,\ it's\ heading\n\[aspect\]:\ While\ the\ \[\[`\[for\]`\]\ code\ above\ suffers\ in\ readability,\ it's\ heading\ndown\ a\ useful\ path.\ \[Lisp\]ers\ would\ tend\ to\ look\ for\ an\ underlying\ abstraction\n\n======\nproc\ with-records\ \{eofchar\ \$_record\ body\}\ \{\n\ \ \ \ upvar\ 1\ \$_record\ record\n\ \ \ \ set\ _eofchar\ \[fconfigure\ \$pipe\ -eofchar\]\n\ \ \ \ for\ \{fconfigure\ \$pipe\ -eofchar\ \$eofchar\}\ \{\n\ \ \ \ \ \ \ \ \[string\ length\ \[set\ record\ \[read\ \$pipe\]\]\]\n\ \ \ \ \}\ \{seek\ \$pipe\ 1\ current\}\ \{\n\ \ \ \ \ \ \ \ uplevel\ 1\ \$body\n\ \ \ \ \}\n\ \ \ \ fconfigure\ \$pipe\ -eofchar\ \$_eofchar\n\}\n======\n\nIn\ writing\ this\ construct,\ the\ need\ to\ reset\ `-eofchar`\ at\ the\ end\ of\ the\ look\nwas\ exposed\ and\ easily\ addressed.\ Also\ I'd\ tend\ to\ use\ the\ default\ name\ `\$_`\nfor\ the\ record\ instead\ of\ having\ to\ explicitly\ provide\ it,\ but\ that's\ a\ matter\nof\ taste,\ as\ is\ the\ name\ of\ the\ procedure,\ which\ I'm\ not\ entirely\ happy\ with.\nof\ taste.\ \ As\ is\ the\ name\ of\ the\ procedure,\ which\ I'm\ not\ entirely\ happy\ with.\nBut\ the\ point\ is\ that\ making\ \[New\ Control\ Structures\]\ is\ easy:\ you\ don't\ have\nto\ be\ shoehorn\ your\ problem\ into\ \[\[`\[for\]`\],\ \[\[`\[foreach\]`\]\ and\ \[\[`\[while\]`\]\n\n\n\n**\ Tips\ and\ Tricks\ on\ `for`\ **\n**\ Tips\ and\ Tricks\ on\ \[\[`\[for\]`\]\ **\nA\ poster\ to\ \[comp.lang.tcl\]\ mentioned\ the\ following\ problem.\ Some\ code\ was\ set\nup\ like\ this:\n\n======\nset\ size\ \[getresult\ from\ operation\]\nfor\ \{set\ i\ 0\}\ \{\$i<\$size\}\ \{incr\ i\}\ \{\n\ \ \ \ set\ workingarray(\$i)\ 0\n\}\n======\n\nHowever,\ due\ to\ a\ mistake,\ the\ output\ from\ `getresult`\ changed\ at\ one\ point\nHowever,\ due\ to\ a\ mistake,\ the\ output\ from\ \[\[getresult\]\ changed\ at\ one\ point\nfrom\ being\ a\ number\ to\ being\ a\ string.\ \ Rather\ than\ causing\ for\ to\ raise\ an\nerror,\ the\ bug\ caused\ the\ for\ loop\ to\ loop\ thousands\ of\ time,\ until\ in\ the\n\nWhile\ \n\n======\nexpr\ \$i\ <\ \$size\n======\n\nwould\ raise\ an\ error\n\n======\nexpr\ \{\$i<\$size\}\n======\n\n,\ as\ well\ as\ the\ use\ within\ the\ `for`\ only\ returns\ a\ 1,\ causing\ the\ loop\ to\ run\nas\ well\ as\ the\ use\ within\ the\ for\ only\ returns\ a\ 1,\ causing\ the\ loop\ to\ run\n\nTest\ your\ variables\ to\ ensure\ they\ actually\ have\ the\ type\ of\ value\ you\ expect,\nafter\ getting\ values\ from\ a\ user\ or\ external\ source.\n\nA\ quick\ way\ to\ \[assert\]\ that\ a\ value\ is\ an\ integer\ is\ to\ `\[incr\]`\ it\ by\ `0`,\ like\nA\ quick\ way\ to\ \[assert\]\ that\ a\ value\ is\ an\ integer\ is\ to\ \[incr\]\ it\ by\ 0,\ like\n\n======\nset\ size\ \[getresult\ from\ operation\]\nincr\ size\ 0\nfor\ \{set\ i\ 0\}\ \{\$i<\$size\}\ \{incr\ i\}\ \{\n\ \ \ \ set\ workingarray(\$i)\ 0\n\}\n======\n\n\n<<categories>>\ Arts\ and\ Crafts\ of\ Tcl-Tk\ Programming\ |\ Tcl\ syntax\ help\ |\ Command\ |\ Control\ Structure} CALL {my revision for} CALL {::oo::Obj1396430 process revision/for} CALL {::oo::Obj1396428 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