Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/list?V=228
QUERY_STRINGV=228
CONTENT_TYPE
DOCUMENT_URI/revision/list
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.70.39.217
REMOTE_PORT57862
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR34.227.112.145
HTTP_CF_RAY86b777e3ecf50849-IAD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTclaudebot
HTTP_CF_CONNECTING_IP34.227.112.145
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 list '''\[http://www.tcl.tk/man/tcl/TclCmd/list.htm%|%list\]''',\ a\ \[Tcl\ Commands%|%built-in\]\ \[Tcl\]\ \[command\],\ creates\ a\ \[Tcl\ Rules\ Redux%|%list\].\n\n\n\n**\ Synopsis\ **\n\n\ \ \ \ :\ \ \ '''list'''\ ?''arg\ arg\ ...''?\ \n\n\n\n**\ Summary\ **\n\nReturns\ a\ list\ whose\ elements\ are\ the\ given\ ''arg''\ values\ (in\ the\ same\ order).\nReturns\ an\ empty\ list\ if\ no\ arguments\ are\ given.\n\n\n\n**\ Documentation\ **\n\n\ \ \ \[http://www.tcl.tk/man/tcl/TclCmd/list.htm%|%man\ page\]:\ \ \ \n\n\ \ \ \[http://core.tcl.tk/tcl/artifact?filename=generic/tclUtil.c&ci=trunk%|%generic/tclUtil.c\]:\ \ \ documentation\ of\ the\ list\ format\n\ \ \ \n\ \ \ \[tip%|%Tip\]\ \[http://www.tcl.tk/cgi-bin/tct/tip/407%|%407\],\ The\ String\ Representation\ of\ Tcl\ Lists:\ the\ Gory\ Details:\ \ \ \n\ \ \ \n\ \ \ \[tip%|%Tip\]\ \[http://www.tcl.tk/cgi-bin/tct/tip/148.html%|%148\],\ Correct\ \[\[list\]\]-Quoting\ of\ the\ '#'\ Character:\ \ \ \n\n\n\n**\ See\ Also:\ **\n\n\ \ \ \[Tcl\ Quoting\]:\ \ \ \n\n\ \ \ \[Is\ everything\ a\ list?\]:\ \ \ \n\n\ \ \ \[Additional\ list\ functions\]:\ \ \ \n\n\ \ \ \[Chart\ of\ existing\ list\ functionality\]:\ \ \ \n\n\ \ \ \[Chart\ of\ proposed\ list\ functionality\]:\ \ \ \n\n\ \ \ \[Internal\ organization\ of\ the\ list\ extension\]:\ \ \ \n\n\ \ \ \[pure\ list\]:\ \ \ A\ Tcl\ value\ for\ which\ no\ string\ representation\ has\ been\ generated,\ but\ for\ which\ an\ internal\ structured\ representation\ has.\ \n\n\ \ \ \[Scripted\ List\]:\ \ \ write\ a\ list\ using\ command\ and\ variable\ substitution,\ without\ having\ to\ escape\ the\ newline\ between\ the\ words,\ and\ with\ the\ ability\ to\ make\ comments\ in\ between\ words\ of\ the\ list\ and\ comment\ out\ some\ words\ of\ the\ list\n\n\ \ \ \[cmdSplit%|%scriptSplit\]:\ \ \ split\ a\ command\ into\ its\ logical\ words,\ taking\ possible\ command\ substitution\ into\ account\n\n\ \ \ \[string\ is\ list\]:\ \ \ \n\n\ \ \ \[Tcl\ syntax\]:\ \ \ \n\n\n\n**\ Standard\ List\ Operations\ **\n\n\ \ \ '''append''':\ \ \ `\[lappend\]`\ and\ `\[lset\]`\n\n\ \ \ '''delete''':\ \ \ `\[lreplace\]`\n\n\ \ \ '''extend''':\ \ \ `\[concat\]`,\ `\[lappend\]`,\ and\ `\[list\]`\n\n\ \ \ '''insert''':\ \ \ `\[linsert\]`,\ `\[lreplace\]`\n\n\ \ \ '''length''':\ \ \ `\[llength\]`\ returns\ the\ length\ of\ the\ list,\ which\ is\ always\ `0`\ or\ greater.\n\n\ \ \ '''prepend''':\ \ \ `\[lreplace\]`\n\n\ \ \ '''search''':\ \ \ `\[lsearch\]`\n\n\ \ \ '''set''':\ \ \ `\[lset\]`\n\n\ \ \ '''retrieve''':\ \ \ `\[lindex\]`\ retrieves\ an\ element\ at\ a\ particular\ position.\ \ The\ position\ of\ the\ first\ element\ is\ `0`.\ \ `\[lrange\]`\ retrieves\ a\ list\ of\ elements\ within\ the\ range\ of\ two\ indexes.\ \ `\[lassign\]`\ assigns\ of\ a\ list\ to\ a\ sequence\ of\ variables.\n\ \ \ '''retrieve''':\ \ \ `\[lindex\]`\ retrieves\ an\ element\ at\ a\ particular\ position.\ \ The\ position\ of\ the\ first\ element\ is\ `0`.\ \ `\[lrange\]`\ retrieves\ a\ list\ of\ elements\ within\ the\ range\ of\ two\ indexes.\ \ `\[lassign\]`\ assigns\ of\ a\ list\ to\ a\ sequence\ of\ variables.\n\ \ \ '''transform''':\ \ \ `\[join\]`,\ `\[lmap\]`,\ `\[lrepeat\]`,\ `\[lsort\]`,\ `\[lreverse\]`,\ and\ `\[split\]`\n\n\ \ \ '''validate''':\ \ \ To\ validate\ the\ format\ of\ a\ list,\ use\ `\[lappend\]`\ (with\ only\ one\ argument)\ or\ `\[string\ is\ list\]`.\n\n\n`\[lappend\]`\ and\ `\[lset\]`\ are\ the\ only\ 2\ list\ commands\ which\ use\n`\[lappend\]`,\ `\[lassign\]`,\ and\ `\[lset\]`\ are\ the\ only\ 3\ list\ commands\ which\ use\n'''name\ of\ a\ variable\ containing\ a\ list'''\ rather\ than\ the\ list\ value\ itself.\ \n\n\n\n**\ Description\ **\n\n\n`list`\ creates\ a\ new\ list\ and\ appends\ each\ ''arg''\ to\ the\ list.\ \ If\ no\ ''arg''s\n`list`\ creates\ a\ new\ list\ and\ appends\ each\ ''arg''\ to\ the\ list,\ adding\ \[dodekalogue%|%braces\]\nand\ backslashes\ to\ the\ ''arg''\ value\ such\ that\ if\ the\ new\ list\ is\ passed\ to\n`\[eval\]`,\ each\ argument\ in\ the\ new\ list\ becomes\ a\ \[word\]\ of\ a\ \[command\],\ and\nspecial\ characters\ in\ each\ word\ are\ escaped\ so\ that\ they\ have\ their\ literal\ninterpretations.\ If\ no\ ''arg''s\ are\ given,\ the\ new\ list\ is\ empty.\nA\ '''list'''\ is\ an\ ''ordered\ \[tuple\]\ of\ values''.\ \ In\ other\ languages\ this\ is\nsometimes\ known\ as\ an\ ''array''\ or\ ''vector''.\ \ `\[list\]`\ and\ related\ commands\nformat\ a\ list\ such\ that\ it\ can\ be\ interpreted\ as\ the\ words\ of\ a\ command,\ making\nTcl\ \[homoiconic\]\ (see\ \"lists\ vs\ commands\"\ below).\n\nIn\ contrast\ with\ other\ languages,\ a\ Tcl\ list\ is\ not\ a\ \[data\ structure\],\ but\ a\n\[string\]\ that\ conforms\ to\ a\ specific\ \[data\ format%|%format\]\ derived\ from\ the\n\[dodekalogue%|%rules\]\ of\ Tcl.\ The\ various\ list\ commands\ read\ and\ interpret\ the\nstring\ value\ in\ order\ to\ carry\ out\ their\ operations\ on\ a\ list.\ \ For\nperformance,\ they\ may,\ and\ standard\ Tcl\ list\ commands\ do,\ cache\ a\ structured\ninterpretation\ for\ future\ use,\ but\ this\ is\ an\ implementation\ detail.\ \ Together,\nthis\ list\ format\ and\ the\ commands\ that\ process\ it\ comprise\ an\ \[abstract\ data\ntypes%|%abstract\ data\ type\].\n\nBecause\ a\ list\ is\ a\ string,\ string\ operations\ can\ be\ applied\ to\ it,\ though\ the\ndanger\ exists\ that\ string\ operations\ will\ yield\ an\ invalid\ list.\ \ See\ \"lists\ vs\ndanger\ exists\ that\ string\ operations\ will\ yield\ an\ invalid\ list!\ \ See\ \"lists\ vs\n\nThe\ items\ the\ new\ list\ are\ quoted\ with\ \[dodekalogue%|%braces\]\nUse\ `list`\ to\ safely\ form\ a\ list\ without\ worrying\ about\ how\ to\ properly\nquote\ the\ words\ in\ the\ list.\ \ this\ is\ particularly\ useful\ when\ a\ word\ in\ the\nlist\ contains\ a\ character\ such\ as\ `\{`\ or\ `\"`\ that\ is\ easy\ to\ misquote:\nAlthough\ a\ properly-formatted\ list\ can\ be\ typed\ out\ manually,\ it's\ usually\ best\ to\ use\nlist\ look,\ ma!\ a\ \\\{\ list\ with\ `\"\ weird\ characters\ \\\}\ in\ it\n======\n\n\n\n**\ List\ Format\ **\n\nA\ \[script\]\ that\ contains\ no\ \[script\ substitution%|%command\ substitutions\]\ is\ a\ valid\ list\ composed\ of\ all\ the\ words\ of\ all\ the\ commands\ in\ the\nEvery\ \[script\]\ that\ has\ no\ comment\ lines\ and\ doesn't\ use\ the\ `\[\{*\}\]`\ operator\nis\ a\ valid\ list\ composed\ of\ all\ the\ words\ of\ all\ the\ commands\ in\ the\ script.\nConversely,\ any\ valid\ list\ is\ suitable\ for\ `\[eval%|%evaluation\]`\ as\ a\ \[command\].\nNot\ as\ a\ \[script\],\ but\ as\ a\ command.\nWhen\ \[Tcl\ rules\]\ are\ stripped\ of\ those\ parts\ that\ refer\ to\ the\ operational\ aspects\ of\ command\ evaluation,\ they\ also\ serve\ to\ specify\nthe\ format\ of\ a\ list.\ \ Here\ are\ the\ \[dodekalogue%|%Tcl\ rules\]\ that\ do\ not\ apply\ to\ the\ list\ evaluation:\nspecify\ the\ format\ of\ a\ list.\ \ Here\ are\ the\ \[dodekalogue%|%Tcl\ rules\]\ that\ do\ not\ apply\ to\ the\ list\ evaluation:\n\ \ \ \ '''Evaluation''':\ \ \ Command\ evaluation\ is\ not\ performed.\ Evaluation\ of\ a\ list\ consists\ only\ of\ breaking\ the\ commands\ into\ words.\ \ Each\ \[word\]\ encodes\ an\ element\ of\ the\ list.\ \ The\ first\ word,\ which\ is\ the\ command\ name\ in\ script\ evaluation,\ is\ simply\ the\ first\ value\ in\ the\ list.\n\n\ \ \ \ newline\ and\ semicolon:\ \ \ Since\ no\ commands\ are\ evaluated,\ \ command\ delimiters\ are\ not\ necessary,\ and\ these\ characters\ lose\ that\ special\ meaning.\n\n\ \ \ \ `#`:\ \ \ Because\ no\ routine\ is\ looked\ up\ or\ invoked,\ `#`\ loses\ its\ meaning\ as\ a\ comment\ indicator.\n\n\ \ \ \ '''\[dodekalogue%|%variable\ substitution\]''':\ \ \ Not\ performed.\ \ `\$`\ has\ no\ special\ meaning.\n\n\ \ \ \ '''\[script\ substitution%|%command\ substitution\]''':\ \ \ Since\ no\ routines\ are\ invoked,\ command\ substitution\ is\ not\ performed,\ and\ '''`\[`'''\ \ does\ not\ have\ special\ meaning.\ \n\n\ \ \ \ `\{*\}`:\ \ \ Only\ useful\ for\ script\ evaluation,\ so\ it\ isn't\ performed\ for\ list\ evaluation\n\ \ \ \ `\{*\}`:\ \ \ Only\ useful\ for\ script\ evaluation,\ so\ it\ isn't\ permitted\ for\ list\ evaluation\nIn\ all\ other\ respects,\ list\ evaluation\ is\ identical\ to\ script\ evaluation.\n'''\[Dodekalogue%|%double\ quotes\]''',\ '''\[Dodekalogue%|%braces\]''',\ and\n'''\[Dodekalogue%|%backslash\ substitution\]'''\ are\ all\ processed\ as\ usual.\n\nBeware\ of\ \[double\ substitution\].\ \ Tcl\ does\ its\ standard\ processing\ on\ the\narguments\ to\ `\[list\]`,\ and\ then\ `\[list\]`\ processes\ them\ again.\ \nThe\ \[empty\ string\]\ is\ a\ list\ that\ contains\ no\ words.\n\nEnclosing\ a\ well-formed\ list\ in\ braces\ results\ in\ a\ list\ containing\ exactly\ one\n\[word\],\ which\ is\ the\ original\ list,\ but\ enclosing\ an\ arbitrary\ string\ of\n\[word\],\ which\ is\ the\ original\ list,\ but\ enclosing\ an\ arbitrary\ value\ in\ braces\nsuccesfully\ working\ with\ lists\ in\ Tcl\ is\ to\ understand\ that\ although\ braces\n(`\{`\ and\ `\}`)\ are\ often\ used\ to\ delimit\ individual\ words\ in\ lists,\ braces\ do\nnot\ mean\ \"list\".\ \ They\ are\ simply\ an\ escaping\ mechanism\ for\ some\ of\ Tcl's\nspecial\ characters,\ e.g.,\ whitespace.\ \ As\ \[DGP\]\ put\ it,\ \"Don't\ imagine\ that\nbraces\ have\ magic\ list-ifying\ powers.\"\n\nDouble\ quotes\ and\ braces\ are\ essentially\ syntactic\ sugar\ for\ backslash\ escaping.\ \n\[PYK\]\ 2015-04-16:\ \ For\ example,\ although\ braces\ are\ a\ very\ convenient\ way\ to\nrepresent\ nested\ lists,\ it's\ usually\ possible\ to\ represent\ the\ same\ nested\n\n======\nputs\ \[lindex\ \{a\ \{b\ c\ \{d\ e\ f\ g\}\}\}\ 1\ 2\]\ \;#\ ->\ d\ e\ f\ g\nputs\ \[lindex\ a\\\ b\\\\\\\ c\\\\\\\ d\\\\\\\\\\\\\\\ e\\\\\\\\\\\\\\\ f\\\\\\\\\\\\\\\ g\ 1\ 2\]\ \;#\ ->\ d\ e\ f\ g\n======\n\nNot\ that\ one\ would\ want\ to\ write\ code\ like\ with\ all\ those\ backslashes.\ It\ just\nillustrates\ the\ point\ that\ when\ interpreting\ a\ string\ as\ a\ list,\ braces\ merely\nescape\ the\ normal\ interpretation\ of\ whitespace\ as\ the\ delimiter\ between\nelements\ in\ the\ list.\ They\ are\ only\ indirectly\ involved\ in\ the\ interpretation\nof\ a\ value\ as\ a\ nested\ listed\ by\ virtue\ of\ their\ effect\ on\ whitespace.\ \ Braces\nby\ themselves\ do\ not\ mean\ \"list\".\n\n\n\[AMG\]:\ \"Usually\"\ possible?\ \ I'm\ sure\ you\ mean\ \"always\"\ possible.\ \ Backslash\ quoting\ can\ be\ used\ to\ encode\ any\ value\ whatsoever,\ even\ those\ that\ don't\ play\ nice\ with\ the\ brace\ quoting\ rules,\ e.g.\ a\ string\ containing\ characters\ immediately\ after\ the\ close\ brace.\n\n\[PYK\]\ 2015-04-16:\ \ \ Check.\ \ Make\ that\ \"always\ possible\".\ \ Double\ quotes\ and\nbraces\ are\ essentially\ syntactic\ sugar\ for\ backslash\ escaping.\ \n\n**\ A\ Note\ on\ Terminology\ **\n\n\nThis\ page\ discusses\ both\ the\ syntax\ of\ a\ list\ as\ a\ string\ as\ well\ as\ operations\nIn\ lower-level\ languages,\ a\ list\ is\ implemented\ as\ some\ \[data\ structure\],\ and\nin\ general,\ the\ units\ that\ compose\ a\ data\ structure\ are\ called\ '''elements'''.\nThis\ term\ applies\ to\ data\ structures\ in\ general.\ \ There\ is\ a\ subtle\ but\ndistinct\ difference\ between\ an\ element\ of\ a\ data\ structure\ and\ an\ item\ in\ a\nlist.\ \ In\ a\ data\ structure,\ an\ element\ may\ be\ employed\ to\ represent\ an\n'''item'''\ in\ the\ list,\ but\ it\ may\ also\ contain\ additional\ information,\ such\ as\na\ reference\ to\ the\ element\ containing\ containing\ the\ next\ item\ in\ the\ list,\ for\nexample.\ \ Because\ there\ is\ often\ a\ one-to-one\ relationship\ between\ an\ element\nin\ a\ data\ structure\ and\ an\ item\ in\ the\ list\ the\ data\ structure\ implements,\n\"element\"\ is\ often\ used\ in\ place\ of\ \"item\",\ and\ this\ is\ true\ both\ of\ the\ncontent\ of\ this\ wiki\ and\ the\ Tcl\ documentation.\ \ \"Item\"\ is\ the\ more\ apt\ term.\n\nof\ a\ list\ as\ an\ \[abstract\ data\ type\].\ \ In\ the\ \[dodekalogue%|%rules\]\ of\ Tcl,\ \"word\"\nlist\ as\ an\ \[abstract\ data\ type\].\ \ In\ the\ \[dodekalogue%|%rules\]\ of\ Tcl,\ \"word\"\nformat\ of\ a\ list.\ \ On\ this\ page,\ \"word\"\ is\ used\ in\ this\ technical\ sense\ to\nrefer\ specifically\ to\ a\ component\ of\ a\ string\ that\ represents\ a\ list.\ \ In\ other\nplaces\ it's\ used\ in\ the\ common\ non-technical\ sense.\ \ Enough\ context\ should\ be\nprovided\ to\ differentiate\ the\ two\ meanings.\ \n\n\n\n**\ Lists\ vs\ Commands\ **\n\nBecause\ both\ \[Dodekalogue%|%commands\]\ and\ lists\ use\ whitespace\ to\ delimit\nwords,\ every\ valid\ list\ is\ a\ valid\ script.\ \ However,\ not\ every\nwords,\ every\ valid\ list\ is\ a\ valid\ command.\ \ However,\ not\ every\nvalid\ command\ is\ a\ valid\ list:\n======\n%\ llength\ \{set\ b\ \[list\ \$one\ \"\$two\ \$three\"\]\}\nlist\ element\ in\ quotes\ followed\ by\ \"\]\"\ instead\ of\ space\n======\n\nThe\ `\]`\ at\ the\ end\ of\ the\ command\ is\ a\ violation\ of\ the\n'''\[Dodekalogue%|%double\ quotes\]'''\ rule,\ which\ states\ that\ `\"`\ terminates\ a\nquoted\ word.\ \ A\ space\ could\ be\ added\ to\ turn\ it\ into\ a\ well-formed\ list:\n\n======\n%\ llength\ \{set\ b\ \[list\ \$one\ \"\$two\ \$three\"\ \]\}\n6\n======\n\nNotice\ that\ although\ it\ is\ logically\ a\ three-word\ command,\ because\ of\n\[Dodekalogue%|%command\ substitution\]\ the\ last\ word\ in\ the\ command\ is\ actually\ncomposed\ of\ four\ words\ from\ the\ list.\n\n\n\n**\ Strings\ that\ Are\ Lists\ **\n\nAn\ empty\ string\ is\ an\ empty\ list:\n\n======\n%\ set\ list\ \[list\]\n%\ llength\ \$list\n0\n\n%\ set\ list\ \{\}\n%\ llength\ \$list\n0\n\n%\ set\ list\ \"\"\n%\ llength\ \$list\n0\n======\n\nA\ string\ containing\ nothing\ but\ whitespace\ is\ also\ an\ empty\ list:\n\n======\n%\ set\ list\ \{\ \}\n%\ llength\ \$list\n0\n\n%\ set\ list\ \\n\n%\ llength\ \$list\n0\n\nset\ list\ \\t\\n\\t\nllength\ \$list\ \;#\ ->\ 0\n======\n\nA\ string\ that\ contains\ no\ whitespace\ is\ often,\ but\ not\ always\ a\ list\ (containing\ one\ word):\n\n======\n%\ set\ list\ hello\n%\ llength\ \$list\n1\n\n%\ set\ list\ he\\\{llo\n%\ llength\ \$list\n1\n\n%\ set\ notalist\ \\\{hello\ \n%\ llength\ \$notalist\nunmatched\ open\ brace\ in\ list\n======\n\nThe\ following\ is\ a\ list\ that\ contains\ one\ word,\ which\ is\ an\ empty\ string:\n\n======\n%\ set\ list\ \{\{\}\}\n%\ llength\ \$list\n1\n\n%\ set\ list\ \[list\ \{\}\]\nllength\ \$list\ \;#\ ->\ 1\n======\n\nWhitespace\ separates\ words\ in\ a\ list:\n\n======\n%\ set\ list\ \{1\ 2\}\n%\ llength\ \$list\n2\n\n%\ set\ list\ \"1\ 2\"\n%\ llength\ \$list\n2\n======\n\nHere\ is\ a\ list\ that\ contains\ two\ words,\ both\ of\ which\ are\ empty\ strings:\n\n======\n%\ set\ list\ \{\{\}\ \{\}\}\n%\ llength\ \$list\n2\n======\n\n\nList\ commands\ parse\ strings\ into\ lists\ in\ much\ the\ same\ way\ that\ Tcl\ parses\nstrings\ into\ commands.\ \ In\ the\ following\ example,\ `\[llength\]`\ parses\ the\ string\ninto\ a\ list,\ and\ the\ backlash-space\ sequence\ results\ in\ the\ first\ character\ of\nthe\ second\ word\ being\ a\ space\ character:\n\n======\n%\ set\ list\ \{1\ \\\ 2\}\n%\ llength\ \$list\n2\n======\n\nIt\ is\ very\ common,\ and\ perfectly\ acceptable,\ to\ use\ braces\ instead\ of\ `list`\nwhen\ writing\ a\ list:\n\n======\n%\ set\ list\ \{one\ two\ three\}\n%\ llength\ \$list\n3\n======\n\nBut\ in\ Tcl,\ braces\ are\ simply\ a\ means\ of\ escaping\ whitespace\ and\ other\ special\ncharacters\ in\ strings.\ \ They\ are\ a\ nice\ way\ to\ write\ out\ lists,\ but\ Tcl\ itself\ndoesn't\ equate\ braces\ with\ lists.\ \ Any\ quoting\ can\ be\ used\ to\ make\ a\nwell-formed\ list,\ and\ there\ are\ an\ infinite\ number\ of\ ways\ to\ produce\ a\ string\nthat\ is\ the\ same\ well-formed\ list:\n\n======\n%\ set\ list\ \"one\ two\ three\"\n%\ llength\ \$list\n3\n\n%\ set\ list\ one\\\ two\\\ three\n%\ llength\ \$list\n3\n\n%\ set\ list\ one\\x20two\\x20three\n%\ llength\ \$list\n3\n\n%\ set\ list\ one\\ttwo\\tthree\\t\n%\ llength\ \$list\n3\n\n#...\ and\ on\ and\ on\ ...\n======\n\n\nWhen\ formatting\ a\ list\ as\ a\ string,\ `list`\ will\ escape\ values\ where\ necessary:\n\n======\n%\ list\ \\n\\\{\n\\n\\\{\n======\n\n\n\n**\ Strings\ that\ Are\ Not\ Lists\ **\n\n\[EIAS%|%All\ lists\ are\ strings\],\ but\ not\ all\ strings\ are\ well-formed\ lists.\ \ The\nvarious\ list\ commands\ expect\ their\ arguments\ to\ be\ well-formed\ lists.\n\n\nTo\ check\ whether\ a\ string\ is\ a\ list:\ \n\n======\nstring\ is\ list\ \$somevariable\n======\n\nAlternatively:\n\n======\ncatch\ \{llength\ \$somevariable\}\n======\n\nWhen\ doing\ experiments\ to\ understand\ lists,\ it\ is\ a\ good\ idea\ to\ first\ assign\nthe\ values\ in\ question\ to\ variables\ before\ operating\ on\ them,\ since\ it\ is\ hard\nto\ keep\ track\ of\ when\ quoting\ is\ interpreted\ as\ Tcl\ parses\ the\ command,\ \ and\nwhen\ the\ command\ is\ interpreting\ the\ values\ it\ has\ received\ as\ arguments.\ This\nmakes\ it\ possible\ to\ first\ inspect\ the\ value\ of\ the\ string\ before\ passing\ it\ to\na\ command:\n\n======\n%\ set\ var1\ \\\{\n\{\n======\n\nMany\ simple\ strings\ are\ lists:\n\n======\n%\ llength\ hello\n1\n%\ llength\ hello\\\ world\ \n2\n%\ llength\ \{how\ I\ made\ a\ great\ mistake\ in\ quotation\}\n8\n======\n\nSome\ strings,\ however,\ are\ '''not'''\ lists:\n\n======\n%\ llength\ \\\"\nunmatched\ open\ quote\ in\ list\n\n%\ llength\ \\\{\nunmatched\ open\ brace\ in\ list\n\n%\ llength\ \"ab\{\ \{x\ y\"\nunmatched\ open\ brace\ in\ list\n\n%\ llength\ \\\{\}a\nlist\ element\ in\ braces\ followed\ by\ \"a\"\ instead\ of\ space\n\n%\ llength\ \{\{a\ b\}\ \{c\}\]\}\nlist\ element\ in\ braces\ followed\ by\ \"\]\"\ instead\ of\ space\n\n%\ llength\ \{\{*\}exactitude\}\nlist\ element\ in\ braces\ followed\ by\ \"exactitude\"\ instead\ of\ space\n======\n\n\n\n**\ Canonical\ Representation\ **\n\nA\ single\ list\ may\ be\ represented\ by\ different\ combinations\ of\ double\ quotes,\ braces,\ and\nA\ single\ list\ may\ be\ represented\ by\ different\ of\ double\ quotes,\ braces,\ and\nbut\ the\ latter\ is\ the\ canonical\ representation\ of\ the\ list.\n\nTo\ produce\ the\ canonical\ representation\ of\ a\ list:\n\n======\nlist\ \{*\}\$somelist\n======\n\nOne\ quick\ and\ dirty\ way\ to\ check\ for\ list\ equality\ is\ to\ compare\ their\ncanonical\ representations\ as\ a\ string:\n\n======\nexpr\ \{\[list\ \{*\}\$list1\]\ eq\ \[list\ \{*\}\$list2\]\}\n======\n\nThis\ may\ be\ undesirable\ if\ the\ lists\ are\ large,\ because\ the\ string\ values\ of\nboth\ `\$list1`\ and\ `\$list2`\ are\ generated\ if\ they\ haven't\ been\ already.\n\nAnother\ thing\ `list\ \{*\}\$list1`\ does\ is\ armor\ special\ characters\ against\npossible\ interpretation\ if\ evaluated\ as\ a\ Tcl\ script:\n\n======\n%\ list\ \{*\}\{puts\ \$hello\;\ set\ b\ \[list\ \$one\ \$two\ \$three\]\}\nputs\ \{\$hello\;\}\ set\ b\ \{\[list\}\ \{\$one\}\ \{\$two\}\ \{\$three\]\}\n======\n\nIn\ other\ words,\ a\ list\ is\ formed\ such\ that\ the\ following\ is\ true\n(\[http://wiki.tcl.tk/440#pagetocad1fdaa5%|%1\]):\n\n======\nexpr\ \{\[eval\ list\ \$list\]\ eq\ \[list\ \{*\}\$list\]\}\n======\n\n\n\n**\ Using\ Braces\ to\ Write\ Lists\ **\n\nIn\ source\ code,\ braces\ are\ often\ used\ to\ write\ lists.\ \ One\ example\ is\ the\narguments\ to\ `\[proc\]`:\n\n======\nproc\ move\ \{element\ speed\ args\}\ ...\n======\n\nIt\ would\ be\ a\ bit\ awkward,\ and\ a\ bit\ slower,\ to\ use\ `list`\ for\ that:\n\n======\nproc\ move\ \[list\ element\ speed\ args\]\ ...\n======\n\nLikewise,\ literal\ braced\ strings\ are\ used\ with\ `\[switch\]`\ (in\ the\ braced\npatterns-and-bodies\ form),\ and\ `\[string\ map\]`\ (the\ map\ is\ a\ list).\ These\nbraced\ strings\ are\ usually\ not\ a\ problem,\ but\ you\ may\ need\ to\ think\ about\ list\ formatting\ when\ special\ characters\ (backslash,\ braces,\ whitespace,\ quotes)\ are\ninvolved.\ Sometimes,\ an\ extra\ layer\ of\ braces\ are\ required\ around\ a\ word\ in\ a\ list,\ but\ if\ it\ is\ unbalanced\ with\ respect\ to\ braces\ then\ you\ may\ need\ to\nbackslash-escape\ all\ special\ characters\ in\ it\ instead.\n\nBraces\ are\ also\ used\ to\ escape\ the\ body\ of\ a\ `\[proc\]`,\ but\ in\ that\ case,\ the\ body\ is\ not\ parsed\ as\ a\ list,\ but\ as\ a\ script\ (unescaped\ newlines\ take\ on\ special\ meaning):\n\n======\nproc\ myproc\ \{\}\ \{\n\ \ \ \ this\n\ \ \ \ is\ not\n\ \ \ \ parsed\ as\ a\ list,\n\ \ \ \ but\ as\ a\ script\n\}\n======\n\n\n**\ Generating\ Code\ **\n\nTcl\ is\ a\ dynamic\ language\ which\ allows\ for\ the\ construction\ of\ Tcl\ scripts\ at\nruntime.\ \ Since\ each\ command\ is\ a\ list,\ and\ a\ script\ is\ a\ sequence\ of\ lists,\nlist\ operations\ are\ often\ used\ to\ build\ up\ commands\ and\ scripts\ that\ can\ then\nbe\ interpreted\ using\ `\[eval\]`,\ `\[apply\]`\ and\ friends.\ \ When\ substituting\ some\npiece\ of\ information\ into\ the\ dynamically-generated\ script,\ it\ is\ usually\nnecessary\ to\ subtitute\ in\ a\ list,\ even\ if\ the\ context\ requires\ a\ single\ value.\n\[string\ map\]\ is\ can\ be\ used\ for\ this\ purpose.\n\n----\n\n\[KBK\]\ writes\ on\ comp.lang.tcl\ (with\ some\ modifications):\n\nIf\ a\ string\ has\ been\ built\ up\ using\ the\ list\ commands,\ for\ instance\ `\[list\]`\ and\n`\[lappend\]`,\ then\ it\ is\ always\ well-formed\ as\ a\ command.\ \ The\ first\ word\ of\nthe\ list\ (word\ number\ zero)\ will\ be\ the\ command\ name\ and\ the\ remaining\nwords\ will\ be\ what\ the\ command\ sees\ as\ its\ parameters.\ \ This\ method,\ in\nfact,\ is\ one\ of\ only\ a\ very\ few\ ways\ to\ construct\ command\ strings\ that\ have\ the\ndesired\ parameters\ when\ one\ or\ more\ of\ the\ parameters\ contains\ user-supplied\ndata,\ possibly\ including\ nasties\ like\ backslashes\ or\ unbalanced\ braces.\n\nIn\ particular,\ using\ double-quotes\ and\ the\ string\ commands\ such\ as\ `\[append\]`\nand\ `\[subst\]`\ is\ NOT\ safe\ for\ constructing\ command\ strings\ with\ arbitrary\ data.\n\nMoreover,\ `\[eval\]`\ and\ its\ friends\ give\ you\ special\ support\ for\ the\ technique\nof\ using\ lists\ as\ commands.\ \ If\ a\ command\ being\ evaluated\ is\ a\ \"pure\"\ list,\nthat\ is,\ one\ that\ was\ constructed\ using\ the\ list\ commands\ and\ has\ never\nacquired\ a\ string\ representation,\ then\ the\ evaluator\ is\ able\ to\ short-circuit\nthe\ parsing\ process,\ knowing\ that\ all\ arguments\ have\ been\ substituted.\ \ It\ndoesn't\ need\ to\ do\ the\ (fairly\ expensive)\ scan\ for\ \$-\ \[\]-\ and\ \\-\ substitution,\nnor\ balance\ \"\"\ and\ \{\},\ but\ can\ go\ directly\ to\ looking\ up\ the\ command\ name\ and\ninvoking\ it.\n\n\n\n\n**\ Using\ List\ to\ Concatenate\ Lists\ **\n\n`list`\ can\ be\ used\ with\ \[\{*\}\]\ to\ the\ same\ effect\ as\ `\[concat\]`:\n\n======\nset\ a\ \{a\ b\ c\}\;\ set\ b\ \{d\ e\ f\}\nlist\ \$a\ \$b\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ ->\ \{a\ b\ c\}\ \{d\ e\ f\}\nconcat\ \$a\ \$b\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ ->\ a\ b\ c\ d\ e\ f\nlist\ \{*\}\$a\ \{*\}\$b\ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ ->\ a\ b\ c\ d\ e\ f\n======\n\nSee\ \[Concatenating\ lists\]\ for\ a\ timing\ comparison\ of\ the\ various\ methods.\n\n\n\n**\ \ Concatenating\ Lists\ **\n\nThe\ following\ three\ methods\ for\ concatenating\ list\ are\ roughly\ equivalent\ in\nperformance:\n\n======\nset\ list\ hello\nconcat\ \$list\ \$list\nlist\ \{*\}\$list\ \{*\}\$list\nlappend\ list\ \{*\}\$list\n======\n\nThe\ difference\ is\ that\ `\[concat\]`\ does\ not\ make\ sure\ its\ arguments\ are\ valid\nlists,\ and\ `\[lappend\]`\ modifies\ `\$list`\n\nBefore\ the\ advent\ of\ the\ \[\{*\}\]\ operator,\ the\ following\ syntax\ was\ used:\n\n======\neval\ \[list\ lappend\ baseList\]\ \$extraList\n======\n\n\n\n**\ Newline-delimited\ Lists\ **\n\nWhen\ writing\ a\ list\ of\ lists\ to\ a\ file,\ it's\ useful\ to\ represent\ it\ using\ the\nnewline\ character\ to\ separate\ the\ words\ of\ the\ lists.\ \ Here's\ how\ to\ do\ that:\n\n======\nforeach\ list\ \$tosave\ \{\n\ \ \ \ puts\ \$chan\ \\\{\n\ \ \ \ foreach\ word\ \$list\ \{\n\ \ \ \ \ \ \ \ puts\ \$chan\ \[list\ \$word\]\n\ \ \ \ \}\n\ \ \ \ puts\ \$chan\ \\\}\n\ \ \ \ puts\ \$chan\ \{\}\n\}\n======\n\nThe\ result\ is\ a\ list\ of\ lists,\ having\ the\ same\ length\ as\ `\$tosave`.\n\n\n\n**\ Internal\ Structured\ Representation\ **\n\n\nInternally,\ Tcl\ tracks\ the\ structure\ of\ the\ list,\ and\ the\ various\ list\ commands\ntake\ advantage\ of\ this\ to\ improve\ performance\ to\ O(1)\ time\ (access\ time\ does\nnot\ depend\ on\ the\ total\ list\ length\ or\ position\ within\ the\ list).\ \ A\ string\nrepresentation\ of\ a\ list\ is\ not\ made\ until\ is\ is\ needed.\ \ Therefore,\ \na\ `\[string\]`\ operation\ on\ a\ large\ list\ may\ incur\ a\ dramatic\ performance/storage\npenalty\ if\ it\ causes\ the\ string\ representation\ has\ to\ be\ generated.\ \ The\ rule\ of\ of\ thumb\nis\ to\ use\ list-aware\ commands\ for\ lists,\ and\ avoid\ string\ commands.\ \ One\ obvious\ exception\ to\ this\ rule\ is\ `\[string\ is\ list\]`,\ which\ is\ smart\ enough\ not\ to\ generate\ the\ string\ representation\ of\ a\ pure\ list.\n\n`\[concat\]`\ is\ a\ string\ operation,\ but\ is\ smart\ enough\ not\ to\ incur\ the\npenalty\ if\ all\ its\ arguments\ are\ pure\ lists.\n\nThe\ internal\ representation\ of\ a\ list\ should\ be\ transparent\ at\ the\ script\nlevel,\ but\ for\ the\ curious:\n\nIn\ the\ \[C\]\ implementation\ of\ Tcl\ 8.x,\ a\ list\ is\ a\ type\ of\ \[Tcl_Obj\],\ \ The\nelements\ of\ a\ list\ are\ stored\ as\ C-style\ vectors\ of\ pointers\ to\ the\ individual\n\[Tcl_Obj\]\ element\ values,\ plus\ some\ extra\ data.\ \ The\ consequence\ of\ this\ is\nthat\ `\[llength\]`\ and\ `\[lindex\]`\ are\ constant-time\ operations\ —\ they\ are\nas\ fast\ for\ large\ lists\ as\ they\ are\ for\ small\ lists.\n\n\n\n**\ `\[concat\]`\ **\n\ \ \ \n`\[concat\]`\ also\ operates\ on\ lists,\ but\ does\ not\ require\ that\ its\ arguments\nbe\ valid\ lists.\ `\[foreach\]`\ operates\ on\ lists.\ \ `\[split\]`\ creates\ lists,\nand\ `\[join\]`\ consumes\ them.\ \ Various\ other\ commands\ also\ make\ use\ of\ lists.\n\nSince\ all\ values,\ including\ lists,\ \[EIAS%|%are\ strings\]\ (but\ not\ all\ strings\ are\ lists!),\ it\ is\ possible\ to\ use\ `\[string\]`\ commands\ on\nlists,\ but\ performance\ can\ suffer\ and\ there\ are\ usually\ better\ ways\ to\naccomplish\ the\ task.\ \ In\ some\ common\ cases,\ Tcl\ is\ smart\ enough\ to\ do\ the\ right\ thing.\ \ For\ example,\ doing\ a\ string\ comparision\ between\ a\ list\ and\ the\ empty\ string\ is\ perfectly\ acceptable,\ and\ just\ as\ performant\ as\ the\ `\[llength\]`\ variant:\n\n======\nproc\ foo\ \{bar\ args\}\ \{\n\ \ \ \ if\ \{\$args\ eq\ \{\}\}\ then\ \{\ #string\ comparison\ might\ force\ internal\ Tcl\ gyrations\n\ \ \ \ \ \ \ \ set\ args\ \$::foo::default_for_args\n\ \ \ \ \}\n\ \ \ \ #\ ...\n\}\n======\n\nThe\ `\[llength\]`\ variant:\n\n======\nproc\ foo\ \{bar\ args\}\ \{\n\ \ \ \ if\ \{\[llength\ \$args\]\ ==\ 0\}\ then\ \{\ #\ \$args\ is\ empty\n\ \ \ \ \ \ \ \ set\ args\ \$::foo::default_for_args\n\ \ \ \ \}\n\ \ \ \ #\ ...\n\}\n======\n\n\n**\ Layers\ of\ Interpretation\ **\n\nIn\ the\ following\ example,\ the\ value\ of\ `a_single_backslash`\ is\ a\ single\ backslash:\n\n======\nset\ a_single_backslash\ \[lindex\ \\\\\\\\\ 0\]\n======\n\nprior\ to\ evaluating\ the\ lindex\ command,\ Tcl\ performs\ backslash\ substitution\ on\nthe\ four\ backslashes,\ so\ that\ the\ first\ argument\ becomes\ two\ backslashes.\ \ To\nconvert\ the\ first\ argument\ to\ a\ list,\ the\ `\[lindex\]`\ command\ then\ performs\nbackslash\ on\ substitution\ on\ the\ two\ backslashes,\ resulting\ in\ one\ backslash,\nwhich\ is\ then\ assigned\ to\ `a_single_backslash`.\n\n\n\n**\ Converting\ a\ String\ to\ a\ List\ **\n\n`\[split\]`\ takes\ a\ string\ and\ returns\ a\ list,\ but\ the\ best\ choice\ depends\ on\nthe\ task\ at\ hand.\ `\[regexp\]`\ is\ often\ handy:\n\n======\nset\ wordList\ \[regexp\ -all\ -inline\ \{\\S+\}\ \$myGnarlyString\]\n======\n\n\n\[DKF\]\ proposed\ this\ pretty\ alias:\n\n======\ninterp\ alias\ \{\}\ listify\ \{\}\ regexp\ -all\ -inline\ \{\\S+\}\n======\n\ \n\[Bill\ Paulson\]\ notes\ that\ this\ alias\ changes\ all\ white\ space\ to\ a\ single\ space,\ \nwhich\ might\ or\ might\ not\ be\ what\ you\ want.\n\nOther\ than\ that,\ this\ '''listify'''\ is\ effectively\ a\ `\[split\]`\ that\ interprets\ adjacent\ delimiters\ as\ as\ a\ single\ delimiter\ rather\ than\ interpreting\ them\ as\ delimiting\ an\ empty\ string,\ like\ `\[split\]`\ does.\n\n\n(2014-09-08):\ this\ can\ also\ be\ used\ to\ duplicate\ words\ in\ a\ list:\n\[PL\]\ (2014-09-08):\ this\ can\ also\ be\ used\ to\ duplicate\ words\ in\ a\ list:\n======\nregexp\ -all\ -inline\ \{\\S+\}\ \{a\ b\ c\}\n#\ =>\ a\ b\ c\nregexp\ -all\ -inline\ \{(\\S+)\}\ \{a\ b\ c\}\n#\ =>\ a\ a\ b\ b\ c\ c\nregexp\ -all\ -inline\ \{((\\S+))\}\ \{a\ b\ c\}\n#\ =>\ a\ a\ a\ b\ b\ b\ c\ c\ c\n======\n\netc.\n\n\n**\ Validating\ a\ List\ **\n\nVarious\ ways\ to\ check\ whether\ a\ string\ is\ a\ list:\n\n======\nstring\ is\ list\ \$some_value\ncatch\ \{lindex\ \$some_value\ 0\}\ncatch\ \{llength\ \$some_value\}\n======\n\nIn\ later\ versions\ of\ Tcl,\ \[string\ is\ list\]\ is\ available.\n\n\n\n**\ List\ Vs.\ List\ of\ Lists\ **\n\n\[escargo\]\ 2003-03-16:\ How\ can\ you\ tell\ if\ a\ value\ is\ a\ string\ of\ words\ '''or'''\na\ list\ of\ strings\ of\ words?\n\nThe\ practical\ application\ that\ I\ had\ for\ this\ was\ an\ error-printing\ proc.\ It\ncould\ be\ passed\ a\ value\ that\ might\ be\ a\ single\ error\ message\ or\ a\ list\ of\ error\nmessages.\ \ If\ it\ were\ a\ single\ error\ message,\ then\ I\ could\ print\ it\ on\ one\nline\;\ if\ it\ were\ multiple\ messages,\ then\ I\ wanted\ to\ print\ each\ on\ its\ own\nline.\n\nSo,\ how\ could\ I\ distinguish\ between\ the\ cases?\n\nI\ think\ I\ eventually\ made\ all\ sources\ of\ errors\ provide\ a\ list\ of\ errors,\ even\nif\ was\ always\ a\ list\ of\ 1\ (instead\ of\ just\ the\ error\ message\ string).\n\nBut\ the\ question\ always\ stuck\ with\ me?\ \ Was\ there\ a\ way\ I\ could\ have\ easily\ndistinguished\ between\ the\ two?\ \ Could\ I\ look\ at\ the\ representation\ and\ see\ an\nopening\ curly\ brace\ if\ it\ were\ a\ list?\n\n\[RS\]:\ The\ (outer)\ curlies\ are\ not\ part\ of\ the\ list\ -\ they\ are\ added,\ or\ parsed\naway,\ when\ needed.\n\nTcl\ \[list\]s\ are\ not\ fundamentally\ different\ from\ strings,\ rather,\ I'd\ say\ they\nare\ a\ \"view\"\ on\ strings.\ Just\ as\ `42`\ can\ be\ viewed\ as\ string,\ or\ integer,\ it\ncan\ also\ be\ viewed\ as\ a\ one-word\ list.\ Except\ if\ you\ introduce\ your\ own\ntagging\ convention,\ there\ is\ no\ way\ of\ telling\ whether\ a\ list\ is\ in\ reality\ a\nstring\ -\ in\ the\ other\ direction,\ only\ strings\ that\ cannot\ be\ parsed\ as\ lists\n(unbalanced\ braces,\ quotes..)\ cannot\ be\ viewed\ as\ lists.\ But\ for\ your\ concrete\nerror-printing\ problem:\ if\ you\ simplify\ the\ interface\ to\ \"a\ list\ of\ one\ or\ more\nerror\ messages\",\ you\ can\ have\ the\ desired\ effect\ with\n\n======\nputs\ \[join\ \$errormessages\ \\n\]\n======\n\nJust\ make\ sure\ that\ the\ \"one\ message\"\ case\ is\ properly\ nested,\ e.g.\n\n======\nerrorprint\ \{\{This\ is\ a\ one-liner\}\}\nerrorprint\ \"\{This\ too,\ with\ a\ \$variable\ reference\}\"\ \;#\ braces\ in\ quoted\ strings\ allow\ substitution\nerrorprint\ \[list\ \"another\ \$variable\ reference\"\]\nerrorprint\ \{\{Two\ messages:\}\ \{This\ is\ the\ second\}\}\n======\n\n\n\n**\ Single-word\ Lists\ vs\ non-list\ value\ **\n\nMany\ simple\ string\ values\ can\ also\ be\ interpreted\ as\ single-word\ lists.\nPrograms\ should\ use\ additional\ data\ or\ rely\ on\ program\ logic\ to\ decide\ whether\na\ value\ should\ be\ interpreted\ as\ a\ list\ or\ a\ string.\n\nHere\ is\ another\ way\ of\ looking\ at\ the\ problem\ (`\[lindex\]`\ without\ an\ index\nreturns\ the\ list\ argument\ unchanged):\n\n======\n%\ lindex\ a\na\n%\ lindex\ a\ 0\na\n%\ lindex\ \[lindex\ a\ 0\]\ 0\na\n%\ lindex\ \[lindex\ \[lindex\ a\ 0\]\ 0\]\ 0\na\n%\ lindex\ \{a\}\na\n%\ lindex\ \{a\}\ 0\na\n%\ lindex\ \[lindex\ \{a\}\ 0\]\ 0\na\n%\ lindex\ \[lindex\ \[lindex\ \{a\}\ 0\]\ 0\]\ 0\na\n%\ lindex\ \{\{a\}\}\n\{a\}\n%\ lindex\ \{\{a\}\}\ 0\na\n%\ lindex\ \[lindex\ \{\{a\}\}\ 0\]\ 0\na\n%\ lindex\ \[lindex\ \[lindex\ \{\{a\}\}\ 0\]\ 0\]\ 0\na\n%\ lindex\ \{\{\{a\}\}\}\n\{\{a\}\}\n%\ lindex\ \{\{\{a\}\}\}\ 0\n\{a\}\n%\ lindex\ \[lindex\ \{\{\{a\}\}\}\ 0\]\ 0\na\n%\ lindex\ \[lindex\ \[lindex\ \{\{\{a\}\}\}\ 0\]\ 0\]\ 0\na\n======\n\nNo\ program\ can\ tell\ the\ difference\ between\ the\ string\ \"a\"\ and\ the\ one-word\nlist\ \"a\",\ because\ the\ one-word\ list\ \"a\"\ ''is''\ the\ string\ \"a\".\n\n\[Dossy\]\ 2004-02-26:\ A\ co-worker\ yesterday\ who\ is\ new\ to\ Tcl\ discovered\nsomething\ that\ surprised\ me\ --\ \[nested\ list\]s\ in\ Tcl\ don't\ work\ as\ I\ expected\nin\ a\ very\ specific\ case:\n\n======\n%\ list\ \[list\ \[list\ x\]\]\nx\n======\n\nUm,\ when\ I\ ask\ for\ a\ list\ of\ a\ list\ of\ a\ list\ with\ the\ single\ word\ 'x',\ I\nwould\ expect\ '\{\{\{x\}\}\}'\ back.\ \ However,\ you\ just\ get\ 'x'\ back.\ \ Thinking\ about\nit,\ I\ understand\ why,\ but\ it\ means\ that\ Tcl\ lists\ alone\ cannot\ be\ used\ to\nrepresent\ ALL\ kinds\ of\ data\ structures,\ as\ Tcl\ lists\ magically\ collapse\ when\nit's\ a\ series\ of\ nested\ lists\ with\ the\ terminal\ list\ having\ only\ a\ single\nbare\ word\ that\ requires\ no\ escaping.\n\n\[Lars\ H\]:\ It\ looks\ worse\ than\ it\ is.\ For\ one\ thing,\ it\ is\ only\ the\ string\nrepresentation\ that\ collapses,\ not\ the\ internal\ representation,\ so\ the\ above\nnesting\ of\ `list`\ is\ not\ completely\ pointless.\ It\ is\ furthermore\ very\nuncommon\ (and\ this\ is\ ''not''\ specific\ to\ Tcl)\ that\ nesting\ depth\ alone\ has\ a\nsignificance.\ Either\ you\ know\ the\ structure\ of\ the\ value,\ and\ thereby\ the\nintended\ nesting\ depth,\ or\ the\ list\ is\ some\ generic\ \"thing\",\ and\ in\ that\ case\nyou\ anyway\ need\ a\ label\ specifying\ what\ kind\ of\ thing\ it\ is.\n\n\[DBaylor\]:\ I\ think\ this\ is\ actually\ worse\ than\ it\ looks.\ \ I\ see\ lots\ of\ people\ntrying\ to\ learn\ Tcl\ and\ the\ #1\ point\ of\ confusion\ is\ Dossy's\ example.\ \ But\ what\nI\ really\ dislike\ about\ this\ behavior\ is\ that\ it\ hides\ bugs\ until\ specific\ input\nis\ encountered.\ \ If\ you\ ever\ mix\ up\ your\ data-types\ (string\ vs.\ list),\ your\ncode\ will\ work\ fine\ 99%\ of\ the\ time\ -\ until\ special\ characters\ are\ involved.\nThese\ bugs\ are\ inevitably\ found\ the\ hard\ way.\ \ Oh\ how\ I\ wish\ `\[list\]\ x`\nreturned\ `\{x\}`.\n\n\[PYK\]\ 2013-10-27:\ What\ would\ `\[lindex\]\ x\ 0`\ return,\ then?\ \ An\ error\ that\ `x`\nis\ not\ a\ list?\ \ All\ commands\ are\ lists\ (after\ adjusting\ for\ \[Dodekalogue%|%command\ substitution\]),\ and\ `x`\ is\ potentially\ a\ valid\ command.\nTherefore,\ `x`\ must\ be\ a\ list.\ \ There\ is\ some\ subtlety\ to\ Tcl\ which\ can\ take\ a\nlittle\ time\ for\ beginners\ to\ wrap\ their\ heads\ around,\ but\ this\ subtlety\ is\nTcl's\ strength,\ not\ its\ weakness.\ \ The\ gripe\ about\ hiding\ bugs\ until\ specific\ninputs\ are\ encountered\ is\ a\ gripe\ about\ dynamic\ languages\ in\ general,\ and\ not\nparticular\ at\ all\ to\ Tcl.\n\n\n\n**\ Subsetting\ a\ List\ **\n\n\[LV\]\ Question:\ in\ \[Perl\],\ \[Python\],\ and\ a\ number\ of\ other\ languages,\ one\ has\nthe\ ability\ to\ read\ and\ write\ to\ subsets\ of\ a\ list\ --\ ''slices''\ --\ using\ an\nalmost\ array\ like\ notation.\ \ Is\ this\ something\ that\ one\ could\ simulate\ without\nmuch\ grief\ in\ Tcl?\n\ \n\[RS\]:\ But\ of\ course\ -\ our\ old\ friends\ (with\ wordier\ notation)\n\n======\nset\ slice\ \[lrange\ \$list\ \$from\ \$to\]\nset\ newlist\ \[eval\ lreplace\ \[list\ \$otherlist\]\ \$from\ \$to\ \$slice\]\n======\n\n`\[lset\]`\ can\ only\ replace\ a\ single\ element,\ but\ possibly\ several\ layers\ deep\nin\ the\ nesting.\ For\ reading\ access\ to\ a\ slice\ of\ a\ list,\ check\ \[Salt\ and\ sugar\]\nfor\ how\ the\ following\ is\ implemented:\n\n======\nset\ i\ \[\$\ \{a\ b\ c\ d\ e\ f\ g\}\ 2\ 4\]\ ==>\ \{c\ d\ e\}\n======\n\n\n\n**\ Flattening\ a\ List\ **\n\nTo\ flatten\ a\ list:\n\n======\nconcat\ \{*\}\$nested\n======\n\nIt\ can\ be\ applied\ multiple\ times:\n\n======\nproc\ flatten\ data\ \{\n\ \ \ \ concat\ \{*\}\$data\n\}\nset\ a\ \{\{a\ \{b\ c\}\}\ \{d\ \{e\ f\}\}\}\ \ \;\ #\ \{a\ \{b\ c\}\}\ \{d\ \{e\ f\}\}\nflatten\ \$a\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;\ #\ a\ \{b\ c\}\ d\ \{e\ f\}\nflatten\ \[flatten\ \$a\]\ \ \ \ \ \ \ \ \ \;\ #\ a\ b\ c\ d\ e\ f\n======\n\nalternatively:\n\n======\nset\ flattened\ \[join\ \$mylist\]\n======\n\nAnother\ possibility:\n\n======\nforeach\ e\ \$list\ \{\n\ \ \ \ foreach\ ee\ \$e\ \{\n\ \ \ \ \ \ \ \ lappend\ flatList\ \$ee\n\ \ \ \ \}\n\}\n======\n\n`\[eval\]`\ is\ not\ a\ good\ option\ because\ it\ chokes\ on\ newlines:\n\n======\n%\ eval\ concat\ \{a\nb\}\nambiguous\ command\ name\ \"b\":\ binary\ break\n======\n\nThe\ newline\ in\ the\ argument\ ends\ `\[concat\]`\ and\ starts\ a\ new\ command.\ This\ is\ndue\ neither\ to\ `\[concat\]`\ nor\ to\ the\ \[tclsh\]\ prompt\ loop,\ but\ to\ the\ nature\nof\ `\[eval\]`.\n\nTo\ get\ around\ that\ issue,\ first\ pass\ the\ value\ through\ a\ command\ that\ parses\nstrings\ into\ valid\ lists:\n\n======\neval\ concat\ \[lrange\ \{a\nb\n\}\ 0\ end\]\n======\n\n\n\[RS\]\ 2004-02-26:\ If\ you\ really\ want\ to\ flatten\ a\ list\ of\ any\ depth,\ \ni.e.\ remove\ all\ grouping,\ I\ think\ this\ way\ is\ simplest\ (and\ robust):\n\n======\nproc\ flatten\ list\ \{\n\ \ \ \ string\ map\ \{\\\{\ \"\"\ \\\}\ \"\"\}\ \$list\n\}\n%\ flatten\ \{a\ \{b\ \{c\ d\ \{e\ f\ \{g\ h\}\}\}\}\}\na\ b\ c\ d\ e\ f\ g\ h\n======\n\n\[Lars\ H\]:\ No,\ that\ won't\ work.\ Consider\n\n======\n%\ flatten\ \[list\ \\\{\ \\\}\]\n\\\ \\\n======\n\nI'd\ give\ you\ that\ it\ isn't\ exactly\ clear\ what\ should\ happen\ to\ lists\ with\ such\nwords,\ but\ the\ above\ doesn't\ get\ a\ single\ character\ right.\n\n\[RS\]\ admits\ he\ was\ thinking\ of\ well-behaved\ lists\ (as\ built\ with\ `\[list\]`\nand\ `\[lappend\]`,\ where\ braces\ are\ only\ generated\ mark-up,\ not\ content\ :^)\nYou're\ right\ to\ point\ out\ that\ ''flatten''\ is\ not\ chimpanzee-proof,\ and\ robust,\nenough.\n\n\[cyrilroux\]\ 2010-10-28:\ \ Maybe\ here\ is\ the\ solution\ to\ solve\ the\ escape\ issue?\nThis\ always\ consist\ in\ replacing\ all\ \{\ and\ \}\ but\ NOT\ \\\{\ and\ \\\}\ (escaped\ ones).\nThat\ is\ to\ say\ 6\ cases:\n\n\"^\{\"\n\"\ \{\"\n\"\{\{+\"\n\"\}\$\"\n\"\}\ \"\n\"\}\}+\"\n\n======\nproc\ lflatten\ list\ \{\n\ \ \ \ regsub\ -all\ \{^\\\{|\ \\\{|\\\{\\\{+|\\\}\$|\\\}\ |\\\}\\\}+\}\ \$list\ \{\ \}\ flatten\n\ \ \ \ return\ \$flatten\n\}\n\n%\ set\ foo\ \{\{a\ \{b\ c\}\}\ \{d\\\{d\\\{\ \{e\ f\}\ g\}\}\n%\ lflatten\ \$foo\na\ b\ c\ \ d\{d\{\ e\ f\ g\ \n======\n\n\n\[CMP\]:\ In\ general,\ string\ manipulation\ on\ lists\ all\ have\ the\ same\ problem\;\ they\ndo\ not\ consider\ the\ list\ structure\ (unless\ copying\ the\ complete\ implementation\nof\ the\ existing\ list\ commands).\ \ Hence,\ all\ list\ manipulations\ should\ be\ done\nusing\ existing\ list\ commands.\n\n\n\n**\ Information\ about\ struct::list\ -\ extended\ list\ operations\ **\n\n\[Tcllib\]\ now\ contains\ a\ \[struct::list\]\ module.\ \ Its\ documentation\ can\ be\ found\nat\ http://tcllib.sourceforge.net/doc/struct_list.html.\n\n\[dgp\]\ offers\ this\ example\ of\ making\ use\ of\ it:\n\n\n======\n%\ package\ require\ struct\ 1.3\n1.3\n%\ namespace\ eval\ my\ \{\n\ \ \ \ namespace\ import\ ::struct::list\n\ \ \ \ set\ l\ \[::list\ 1\ 2\ 3\]\n\ \ \ \ puts\ \[list\ reverse\ \$l\]\n\}\n3\ 2\ 1\n======\n\nMore\ explanation…\n\nIn\ the\ above\ example,\ is\ the\ use\ of\ ''::list''\ in\ the\ set\ command\ vs\ ''list''\ in\ the\ \n\[puts\]\ command\ merely\ an\ example\ of\ different\ ways\ of\ referring\ to\ portions,\ or\ does\ one\nrefer\ to\ the\ original\ tcl\ list\ versus\ the\ imported\ new\ list\ command?\n\n\[MG\]\ I\ believe\ ''::list''\ in\ the\ above\ refers\ to\ the\ Tcl\ list\ command,\ and\n''list''\ refers\ to\ the\ imported\ ''::struct::list''\ (which\ is\ then\ also\n''::my::list'',\ as\ it's\ imported).\ \ Or\ at\ least\ I\ think\ that's\ right.\nNamespaces\ used\ like\ that\ require\ a\ lot\ more\ sleep\ than\ I've\ had\ lately\ \;)\n\n\n\n**\ What\ would\ a\ Tcl\ version\ of\ the\ list\ command\ look\ like?\ **\n\n\[AMG\]:\ Is\ this\ an\ acceptable\ implementation\ of\ `list`?\n\n======\nproc\ list\ args\ \{\n\ \ \ \ return\ \$args\n\}\n======\n\nLooks\ right\ to\ me...\n\n\[RS\]:\ To\ me\ too.\ That's\ because\ ''args''\ is\ already\ a\ list,\ as\ by\ the\ Tcl\nparser...\ I'd\ just\ write\n\n\n======\nproc\ list\ args\ \{set\ args\}\n======\n\n\[AMG\]:\ Chuckle.\n\n======\nproc\ list\ args\ \[list\ set\ args\]\n======\n\n\n\n**\ Transform\ a\ list\ into\ a\ list\ of\ fixed\ size\ lists\ **\n\n\[LV\]:\ \ in\ response\ to\ a\ question,\ Jonathan\ Bromley,\ 2008-05-30,\n\[comp.lang.tcl\],\ wrote\ the\ following\ Tcl\ proc\ for\ turning\ a\ long\ list\ into\ a\nlist\ of\ lists:\n\n======\nproc\ split_list\ \{L\ \{n\ 50\}\}\ \{\ \n\ \ \ \ incr\ n\ 0\;\ #\ thanks\ to\ RS\ for\ this\ cool\ \"is\ it\ an\ int\"\ check!\ \n\ \ \ \ set\ result\ \{\}\ \n\ \ \ \ set\ limit\ \[expr\ \{\[llength\ \$L\]\ -\ \$n\}\]\ \n\ \ \ \ for\ \{set\ p\ 0\}\ \{\$p\ <=\ \$limit\}\ \{incr\ p\ \$n\}\ \{\ \n\ \ \ \ \ \ \ \ lappend\ result\ \[lrange\ \$L\ \$p\ \[expr\ \{\$p+\$n-1\}\]\]\ \n\ \ \ \ \}\ \n\ \ \ \ return\ \$result\ \n\}\ \n======\n\n\[arg\]:\ \ Just\ the\ code\ I\ wanted\ (needed\ to\ split\ results\ from\ SQLite).\ Thanks.\nBut\ can\ I\ suggest\ a\ few\ tweaks:-\n\n\ \ \ 1.\ name\ changed\ to\ \"partitionlist\",\ I\ think\ it's\ less\ ambiguous\ than\ \"split_list\".\ Any\ ideas\ for\ a\ better\ name?\n\ \ \ 2.\ change\ default\ from\ 50\ to\ 2,\ splitting\ into\ pairs\ looks\ a\ more\ useful\ default.\n\ \ \ 3.\ change\ setting/comparing\ \"limit\"\ so\ that\ all\ the\ elements\ of\ the\ original\ list\ are\ copied,\ the\ original\ version\ acted\ as\ if\ the\ original\ list\ were\ truncated\ to\ a\ multiple\ of\ the\ requested\ sublist\ length.\ This\ version\ will\ output\ any\ \"extra\"\ elements\ as\ another\ short\ sublist.\n\n======\nproc\ partitionlist\ \{L\ \{n\ 2\}\}\ \{\ \n\ \ \ \ incr\ n\ 0\;\ #\ thanks\ to\ RS\ for\ this\ cool\ \"is\ it\ an\ int\"\ check!\ \n\ \ \ \ set\ result\ \{\}\ \n\ \ \ \ set\ limit\ \[llength\ \$L\]\ \n\ \ \ \ for\ \{set\ p\ 0\}\ \{\$p\ <\ \$limit\}\ \{incr\ p\ \$n\}\ \{\ \n\ \ \ \ \ \ \ \ lappend\ result\ \[lrange\ \$L\ \$p\ \[expr\ \{\$p+\$n-1\}\]\]\ \n\ \ \ \ \}\ \n\ \ \ \ return\ \$result\ \n\}\ \n======\n\n\[Lars\ H\]:\ If\ the\ partitioned\ list\ is\ then\ immediately\ going\ to\ be\ iterated\nover,\ it\ may\ of\ course\ be\ easier\ to\ take\ advantage\ of\ the\ fact\ that\ the\nvariable\ arguments\ of\ \[foreach\]\ are\ really\ lists\ of\ variables.\ I.e.,\ instead\ of\n\n======\nforeach\ row\ \[partitionlist\ \$data\ 3\]\ \{\n\ \ \ \ lassign\ \$row\ first\ second\ third\n\ \ \ \ #\ Further\ processing...\n\}\n======\n\none\ can\ just\ do\n\n======\nforeach\ \{first\ second\ third\}\ \$data\ \{\n\ \ \ \ #\ Further\ processing...\n\}\n======\n\nConversely,\ this\ can\ be\ used\ for\ the\ following\ \[braintwisters\]'\ implementation\ of\ '''partitionlist''':\n\n======\nproc\ partitionlist\ \{L\ \{n\ 2\}\}\ \{\n\ \ \ \ set\ varlist\ \{\}\n\ \ \ \ set\ body\ \{lappend\ res\ \[list\}\n\ \ \ \ for\ \{\}\ \{\$n>0\}\ \{incr\ n\ -1\}\ \{\n\ \ \ \ \ \ \ \ lappend\ varlist\ \$n\n\ \ \ \ \ \ \ \ append\ body\ \{\ \$\}\ \$n\n\ \ \ \ \}\n\ \ \ \ set\ res\ \{\}\n\ \ \ \ foreach\ \$varlist\ \$L\ \[append\ body\ \\\]\]\n\ \ \ \ return\ \$res\n\}\n======\n\n\n**\ Other\ uses\ of\ `\[list\]`\ **\n\n\[AMG\]:\ When\ given\ no\ arguments,\ `\[list\]`\ returns\ empty\ string.\ \ I\ find\ this\nuseful\ when\ entering\ Tcl\ commands\ interactively,\ e.g.\ into\ \[tkcon\]\ or\ \[tclsh\].\nWhen\ I\ know\ that\ a\ command\ will\ produce\ a\ lot\ of\ output,\ such\ as\n`\[read\]`'ing\ a\ whole\ file,\ and\ I\ don't\ want\ to\ have\ it\ all\ on\ my\ screen,\ I\ntack\ \"\;\ list\"\ onto\ the\ end\ of\ my\ command\ line.\n\n======\n\$\ tclsh\n%\ set\ chan\ \[open\ bigfile\]\nfile12dcd00\n%\ set\ data\ \[read\ \$chan\]\;\ list\n%\ close\ \$chan\n======\n\nIf\ not\ for\ the\ `\;\ list`,\ the\ second\ line\ would\ flood\ my\ terminal\ with\ lots\ and\nlots\ of\ garbage.\n\n\[AMG\]:\ Another\ use\ for\ list\ is\ to\ pass\ it\ a\ single\ argument\ which\ it\ will\ then\nreturn.\ \ For\ an\ example,\ see\ SCT\ &\ \[RS\]'s\ comments\ on\ the\ page\ for\ `\[if\]`.\nHowever,\ this\ works\ due\ to\ the\ \"problem\"\ noted\ above\ by\ \[Dossy\]\ 2004-02-26.\nOften\ the\ argument\ requires\ quoting\ to\ become\ a\ single-word\ list,\ in\ which\ncase\ list\ will\ ''not''\ return\ its\ argument\ verbatim.\ \ On\ the\ `\[return\]`\ page\nI\ discuss\ a\ few\ other,\ safer\ approaches.\ \ The\ simplest\ one\ is\ to\ instead\ use\nsingle-argument\ `\[lindex\]`.\n\n\n\n**\ Some\ Tcl\ core\ commands\ require\ lists\ as\ argument\ or\ return\ lists\ **\n\n\ \ \ `\[after\]`:\ \ \ \n\n\ \ \ `\[apply\]`:\ \ \ \n\n\ \ \ `\[array\]`:\ \ \ \n\n\ \ \ `\[binary\]`:\ \ \ \n\n\ \ \ `\[chan\]`:\ \ \ \n\n\ \ \ `\[dde\]`:\ \ \ \n\n\ \ \ `\[dict\]`:\ \ \ \n\n\ \ \ `\[oo::define\]`:\ \ \ \n\n\ \ \ `\[oo::next\]`:\ \ \ \n\n\ \ \ `\[encoding\]`:\ \ \ \n\n\ \ \ `\[exec\]`:\ \ \ \n\n\ \ \ `\[fconfigure\]`:\ \ \ \n\n\ \ \ `\[file\]`:\ \ \ \n\n\ \ \ `\[glob\]`:\ \ \ \n\n\ \ \ `\[http\]`:\ \ \ \n\n\ \ \ `\[info\]`:\ \ \ \n\n\ \ \ `\[interp\]`:\ \ \ \n\n\ \ \ `\[library\]`:\ \ \ \n\n\ \ \ `\[msgcat\]`:\ \ \ \n\n\ \ \ `\[namespace\]`:\ \ \ \n\n\ \ \ `\[open\]`:\ \ \ \n\n\ \ \ `\[package\]`:\ \ \ \n\n\ \ \ `\[packagens\]`:\ \ \ \n\n\ \ \ `\[pid\]`:\ \ \ \n\n\ \ \ `\[pkgMkIndex\]`:\ \ \ \n\n\ \ \ `\[platform\]`:\ \ \ \n\n\ \ \ `\[proc\]`:\ \ \ \n\n\ \ \ `\[read\]`:\ \ \ \n\n\ \ \ `\[oo::refchan\]`:\ \ \ \n\n\ \ \ `\[regexp\]`:\ \ \ \n\n\ \ \ `\[registry\]`:\ \ \ \n\n\ \ \ `\[return\]`:\ \ \ \n\n\ \ \ `\[safe\]`:\ \ \ \n\n\ \ \ `\[scan\]`:\ \ \ \n\n\ \ \ `\[oo::self\]`:\ \ \ \n\n\ \ \ `\[socket\]`:\ \ \ \n\n\ \ \ `\[switch\]`:\ \ \ \n\n\ \ \ `\[tcltest\]`:\ \ \ \n\n\ \ \ `\[tm\]`:\ \ \ \n\n\ \ \ `\[trace\]`:\ \ \ \n\n\n\n**\ Page\ Authors\ **\n\n\ \ \ \[DKF\]:\ \ \ \n\n\ \ \ \[PYK\]:\ \ \ \n\n\n\n**\ References\ **\n\n\ \ \ 1:\ \ \ \[aspect\],\ \[Tcl\ Chatroom\],\ 2014-09-13\n\n regexp2} CALL {my render list '''\[http://www.tcl.tk/man/tcl/TclCmd/list.htm%|%list\]''',\ a\ \[Tcl\ Commands%|%built-in\]\ \[Tcl\]\ \[command\],\ creates\ a\ \[Tcl\ Rules\ Redux%|%list\].\n\n\n\n**\ Synopsis\ **\n\n\ \ \ \ :\ \ \ '''list'''\ ?''arg\ arg\ ...''?\ \n\n\n\n**\ Summary\ **\n\nReturns\ a\ list\ whose\ elements\ are\ the\ given\ ''arg''\ values\ (in\ the\ same\ order).\nReturns\ an\ empty\ list\ if\ no\ arguments\ are\ given.\n\n\n\n**\ Documentation\ **\n\n\ \ \ \[http://www.tcl.tk/man/tcl/TclCmd/list.htm%|%man\ page\]:\ \ \ \n\n\ \ \ \[http://core.tcl.tk/tcl/artifact?filename=generic/tclUtil.c&ci=trunk%|%generic/tclUtil.c\]:\ \ \ documentation\ of\ the\ list\ format\n\ \ \ \n\ \ \ \[tip%|%Tip\]\ \[http://www.tcl.tk/cgi-bin/tct/tip/407%|%407\],\ The\ String\ Representation\ of\ Tcl\ Lists:\ the\ Gory\ Details:\ \ \ \n\ \ \ \n\ \ \ \[tip%|%Tip\]\ \[http://www.tcl.tk/cgi-bin/tct/tip/148.html%|%148\],\ Correct\ \[\[list\]\]-Quoting\ of\ the\ '#'\ Character:\ \ \ \n\n\n\n**\ See\ Also:\ **\n\n\ \ \ \[Tcl\ Quoting\]:\ \ \ \n\n\ \ \ \[Is\ everything\ a\ list?\]:\ \ \ \n\n\ \ \ \[Additional\ list\ functions\]:\ \ \ \n\n\ \ \ \[Chart\ of\ existing\ list\ functionality\]:\ \ \ \n\n\ \ \ \[Chart\ of\ proposed\ list\ functionality\]:\ \ \ \n\n\ \ \ \[Internal\ organization\ of\ the\ list\ extension\]:\ \ \ \n\n\ \ \ \[pure\ list\]:\ \ \ A\ Tcl\ value\ for\ which\ no\ string\ representation\ has\ been\ generated,\ but\ for\ which\ an\ internal\ structured\ representation\ has.\ \n\n\ \ \ \[Scripted\ List\]:\ \ \ write\ a\ list\ using\ command\ and\ variable\ substitution,\ without\ having\ to\ escape\ the\ newline\ between\ the\ words,\ and\ with\ the\ ability\ to\ make\ comments\ in\ between\ words\ of\ the\ list\ and\ comment\ out\ some\ words\ of\ the\ list\n\n\ \ \ \[cmdSplit%|%scriptSplit\]:\ \ \ split\ a\ command\ into\ its\ logical\ words,\ taking\ possible\ command\ substitution\ into\ account\n\n\ \ \ \[string\ is\ list\]:\ \ \ \n\n\ \ \ \[Tcl\ syntax\]:\ \ \ \n\n\n\n**\ Standard\ List\ Operations\ **\n\n\ \ \ '''append''':\ \ \ `\[lappend\]`\ and\ `\[lset\]`\n\n\ \ \ '''delete''':\ \ \ `\[lreplace\]`\n\n\ \ \ '''extend''':\ \ \ `\[concat\]`,\ `\[lappend\]`,\ and\ `\[list\]`\n\n\ \ \ '''insert''':\ \ \ `\[linsert\]`,\ `\[lreplace\]`\n\n\ \ \ '''length''':\ \ \ `\[llength\]`\ returns\ the\ length\ of\ the\ list,\ which\ is\ always\ `0`\ or\ greater.\n\n\ \ \ '''prepend''':\ \ \ `\[lreplace\]`\n\n\ \ \ '''search''':\ \ \ `\[lsearch\]`\n\n\ \ \ '''set''':\ \ \ `\[lset\]`\n\n\ \ \ '''retrieve''':\ \ \ `\[lindex\]`\ retrieves\ an\ element\ at\ a\ particular\ position.\ \ The\ position\ of\ the\ first\ element\ is\ `0`.\ \ `\[lrange\]`\ retrieves\ a\ list\ of\ elements\ within\ the\ range\ of\ two\ indexes.\ \ `\[lassign\]`\ assigns\ of\ a\ list\ to\ a\ sequence\ of\ variables.\n\ \ \ '''retrieve''':\ \ \ `\[lindex\]`\ retrieves\ an\ element\ at\ a\ particular\ position.\ \ The\ position\ of\ the\ first\ element\ is\ `0`.\ \ `\[lrange\]`\ retrieves\ a\ list\ of\ elements\ within\ the\ range\ of\ two\ indexes.\ \ `\[lassign\]`\ assigns\ of\ a\ list\ to\ a\ sequence\ of\ variables.\n\ \ \ '''transform''':\ \ \ `\[join\]`,\ `\[lmap\]`,\ `\[lrepeat\]`,\ `\[lsort\]`,\ `\[lreverse\]`,\ and\ `\[split\]`\n\n\ \ \ '''validate''':\ \ \ To\ validate\ the\ format\ of\ a\ list,\ use\ `\[lappend\]`\ (with\ only\ one\ argument)\ or\ `\[string\ is\ list\]`.\n\n\n`\[lappend\]`\ and\ `\[lset\]`\ are\ the\ only\ 2\ list\ commands\ which\ use\n`\[lappend\]`,\ `\[lassign\]`,\ and\ `\[lset\]`\ are\ the\ only\ 3\ list\ commands\ which\ use\n'''name\ of\ a\ variable\ containing\ a\ list'''\ rather\ than\ the\ list\ value\ itself.\ \n\n\n\n**\ Description\ **\n\n\n`list`\ creates\ a\ new\ list\ and\ appends\ each\ ''arg''\ to\ the\ list.\ \ If\ no\ ''arg''s\n`list`\ creates\ a\ new\ list\ and\ appends\ each\ ''arg''\ to\ the\ list,\ adding\ \[dodekalogue%|%braces\]\nand\ backslashes\ to\ the\ ''arg''\ value\ such\ that\ if\ the\ new\ list\ is\ passed\ to\n`\[eval\]`,\ each\ argument\ in\ the\ new\ list\ becomes\ a\ \[word\]\ of\ a\ \[command\],\ and\nspecial\ characters\ in\ each\ word\ are\ escaped\ so\ that\ they\ have\ their\ literal\ninterpretations.\ If\ no\ ''arg''s\ are\ given,\ the\ new\ list\ is\ empty.\nA\ '''list'''\ is\ an\ ''ordered\ \[tuple\]\ of\ values''.\ \ In\ other\ languages\ this\ is\nsometimes\ known\ as\ an\ ''array''\ or\ ''vector''.\ \ `\[list\]`\ and\ related\ commands\nformat\ a\ list\ such\ that\ it\ can\ be\ interpreted\ as\ the\ words\ of\ a\ command,\ making\nTcl\ \[homoiconic\]\ (see\ \"lists\ vs\ commands\"\ below).\n\nIn\ contrast\ with\ other\ languages,\ a\ Tcl\ list\ is\ not\ a\ \[data\ structure\],\ but\ a\n\[string\]\ that\ conforms\ to\ a\ specific\ \[data\ format%|%format\]\ derived\ from\ the\n\[dodekalogue%|%rules\]\ of\ Tcl.\ The\ various\ list\ commands\ read\ and\ interpret\ the\nstring\ value\ in\ order\ to\ carry\ out\ their\ operations\ on\ a\ list.\ \ For\nperformance,\ they\ may,\ and\ standard\ Tcl\ list\ commands\ do,\ cache\ a\ structured\ninterpretation\ for\ future\ use,\ but\ this\ is\ an\ implementation\ detail.\ \ Together,\nthis\ list\ format\ and\ the\ commands\ that\ process\ it\ comprise\ an\ \[abstract\ data\ntypes%|%abstract\ data\ type\].\n\nBecause\ a\ list\ is\ a\ string,\ string\ operations\ can\ be\ applied\ to\ it,\ though\ the\ndanger\ exists\ that\ string\ operations\ will\ yield\ an\ invalid\ list.\ \ See\ \"lists\ vs\ndanger\ exists\ that\ string\ operations\ will\ yield\ an\ invalid\ list!\ \ See\ \"lists\ vs\n\nThe\ items\ the\ new\ list\ are\ quoted\ with\ \[dodekalogue%|%braces\]\nUse\ `list`\ to\ safely\ form\ a\ list\ without\ worrying\ about\ how\ to\ properly\nquote\ the\ words\ in\ the\ list.\ \ this\ is\ particularly\ useful\ when\ a\ word\ in\ the\nlist\ contains\ a\ character\ such\ as\ `\{`\ or\ `\"`\ that\ is\ easy\ to\ misquote:\nAlthough\ a\ properly-formatted\ list\ can\ be\ typed\ out\ manually,\ it's\ usually\ best\ to\ use\nlist\ look,\ ma!\ a\ \\\{\ list\ with\ `\"\ weird\ characters\ \\\}\ in\ it\n======\n\n\n\n**\ List\ Format\ **\n\nA\ \[script\]\ that\ contains\ no\ \[script\ substitution%|%command\ substitutions\]\ is\ a\ valid\ list\ composed\ of\ all\ the\ words\ of\ all\ the\ commands\ in\ the\nEvery\ \[script\]\ that\ has\ no\ comment\ lines\ and\ doesn't\ use\ the\ `\[\{*\}\]`\ operator\nis\ a\ valid\ list\ composed\ of\ all\ the\ words\ of\ all\ the\ commands\ in\ the\ script.\nConversely,\ any\ valid\ list\ is\ suitable\ for\ `\[eval%|%evaluation\]`\ as\ a\ \[command\].\nNot\ as\ a\ \[script\],\ but\ as\ a\ command.\nWhen\ \[Tcl\ rules\]\ are\ stripped\ of\ those\ parts\ that\ refer\ to\ the\ operational\ aspects\ of\ command\ evaluation,\ they\ also\ serve\ to\ specify\nthe\ format\ of\ a\ list.\ \ Here\ are\ the\ \[dodekalogue%|%Tcl\ rules\]\ that\ do\ not\ apply\ to\ the\ list\ evaluation:\nspecify\ the\ format\ of\ a\ list.\ \ Here\ are\ the\ \[dodekalogue%|%Tcl\ rules\]\ that\ do\ not\ apply\ to\ the\ list\ evaluation:\n\ \ \ \ '''Evaluation''':\ \ \ Command\ evaluation\ is\ not\ performed.\ Evaluation\ of\ a\ list\ consists\ only\ of\ breaking\ the\ commands\ into\ words.\ \ Each\ \[word\]\ encodes\ an\ element\ of\ the\ list.\ \ The\ first\ word,\ which\ is\ the\ command\ name\ in\ script\ evaluation,\ is\ simply\ the\ first\ value\ in\ the\ list.\n\n\ \ \ \ newline\ and\ semicolon:\ \ \ Since\ no\ commands\ are\ evaluated,\ \ command\ delimiters\ are\ not\ necessary,\ and\ these\ characters\ lose\ that\ special\ meaning.\n\n\ \ \ \ `#`:\ \ \ Because\ no\ routine\ is\ looked\ up\ or\ invoked,\ `#`\ loses\ its\ meaning\ as\ a\ comment\ indicator.\n\n\ \ \ \ '''\[dodekalogue%|%variable\ substitution\]''':\ \ \ Not\ performed.\ \ `\$`\ has\ no\ special\ meaning.\n\n\ \ \ \ '''\[script\ substitution%|%command\ substitution\]''':\ \ \ Since\ no\ routines\ are\ invoked,\ command\ substitution\ is\ not\ performed,\ and\ '''`\[`'''\ \ does\ not\ have\ special\ meaning.\ \n\n\ \ \ \ `\{*\}`:\ \ \ Only\ useful\ for\ script\ evaluation,\ so\ it\ isn't\ performed\ for\ list\ evaluation\n\ \ \ \ `\{*\}`:\ \ \ Only\ useful\ for\ script\ evaluation,\ so\ it\ isn't\ permitted\ for\ list\ evaluation\nIn\ all\ other\ respects,\ list\ evaluation\ is\ identical\ to\ script\ evaluation.\n'''\[Dodekalogue%|%double\ quotes\]''',\ '''\[Dodekalogue%|%braces\]''',\ and\n'''\[Dodekalogue%|%backslash\ substitution\]'''\ are\ all\ processed\ as\ usual.\n\nBeware\ of\ \[double\ substitution\].\ \ Tcl\ does\ its\ standard\ processing\ on\ the\narguments\ to\ `\[list\]`,\ and\ then\ `\[list\]`\ processes\ them\ again.\ \nThe\ \[empty\ string\]\ is\ a\ list\ that\ contains\ no\ words.\n\nEnclosing\ a\ well-formed\ list\ in\ braces\ results\ in\ a\ list\ containing\ exactly\ one\n\[word\],\ which\ is\ the\ original\ list,\ but\ enclosing\ an\ arbitrary\ string\ of\n\[word\],\ which\ is\ the\ original\ list,\ but\ enclosing\ an\ arbitrary\ value\ in\ braces\nsuccesfully\ working\ with\ lists\ in\ Tcl\ is\ to\ understand\ that\ although\ braces\n(`\{`\ and\ `\}`)\ are\ often\ used\ to\ delimit\ individual\ words\ in\ lists,\ braces\ do\nnot\ mean\ \"list\".\ \ They\ are\ simply\ an\ escaping\ mechanism\ for\ some\ of\ Tcl's\nspecial\ characters,\ e.g.,\ whitespace.\ \ As\ \[DGP\]\ put\ it,\ \"Don't\ imagine\ that\nbraces\ have\ magic\ list-ifying\ powers.\"\n\nDouble\ quotes\ and\ braces\ are\ essentially\ syntactic\ sugar\ for\ backslash\ escaping.\ \n\[PYK\]\ 2015-04-16:\ \ For\ example,\ although\ braces\ are\ a\ very\ convenient\ way\ to\nrepresent\ nested\ lists,\ it's\ usually\ possible\ to\ represent\ the\ same\ nested\n\n======\nputs\ \[lindex\ \{a\ \{b\ c\ \{d\ e\ f\ g\}\}\}\ 1\ 2\]\ \;#\ ->\ d\ e\ f\ g\nputs\ \[lindex\ a\\\ b\\\\\\\ c\\\\\\\ d\\\\\\\\\\\\\\\ e\\\\\\\\\\\\\\\ f\\\\\\\\\\\\\\\ g\ 1\ 2\]\ \;#\ ->\ d\ e\ f\ g\n======\n\nNot\ that\ one\ would\ want\ to\ write\ code\ like\ with\ all\ those\ backslashes.\ It\ just\nillustrates\ the\ point\ that\ when\ interpreting\ a\ string\ as\ a\ list,\ braces\ merely\nescape\ the\ normal\ interpretation\ of\ whitespace\ as\ the\ delimiter\ between\nelements\ in\ the\ list.\ They\ are\ only\ indirectly\ involved\ in\ the\ interpretation\nof\ a\ value\ as\ a\ nested\ listed\ by\ virtue\ of\ their\ effect\ on\ whitespace.\ \ Braces\nby\ themselves\ do\ not\ mean\ \"list\".\n\n\n\[AMG\]:\ \"Usually\"\ possible?\ \ I'm\ sure\ you\ mean\ \"always\"\ possible.\ \ Backslash\ quoting\ can\ be\ used\ to\ encode\ any\ value\ whatsoever,\ even\ those\ that\ don't\ play\ nice\ with\ the\ brace\ quoting\ rules,\ e.g.\ a\ string\ containing\ characters\ immediately\ after\ the\ close\ brace.\n\n\[PYK\]\ 2015-04-16:\ \ \ Check.\ \ Make\ that\ \"always\ possible\".\ \ Double\ quotes\ and\nbraces\ are\ essentially\ syntactic\ sugar\ for\ backslash\ escaping.\ \n\n**\ A\ Note\ on\ Terminology\ **\n\n\nThis\ page\ discusses\ both\ the\ syntax\ of\ a\ list\ as\ a\ string\ as\ well\ as\ operations\nIn\ lower-level\ languages,\ a\ list\ is\ implemented\ as\ some\ \[data\ structure\],\ and\nin\ general,\ the\ units\ that\ compose\ a\ data\ structure\ are\ called\ '''elements'''.\nThis\ term\ applies\ to\ data\ structures\ in\ general.\ \ There\ is\ a\ subtle\ but\ndistinct\ difference\ between\ an\ element\ of\ a\ data\ structure\ and\ an\ item\ in\ a\nlist.\ \ In\ a\ data\ structure,\ an\ element\ may\ be\ employed\ to\ represent\ an\n'''item'''\ in\ the\ list,\ but\ it\ may\ also\ contain\ additional\ information,\ such\ as\na\ reference\ to\ the\ element\ containing\ containing\ the\ next\ item\ in\ the\ list,\ for\nexample.\ \ Because\ there\ is\ often\ a\ one-to-one\ relationship\ between\ an\ element\nin\ a\ data\ structure\ and\ an\ item\ in\ the\ list\ the\ data\ structure\ implements,\n\"element\"\ is\ often\ used\ in\ place\ of\ \"item\",\ and\ this\ is\ true\ both\ of\ the\ncontent\ of\ this\ wiki\ and\ the\ Tcl\ documentation.\ \ \"Item\"\ is\ the\ more\ apt\ term.\n\nof\ a\ list\ as\ an\ \[abstract\ data\ type\].\ \ In\ the\ \[dodekalogue%|%rules\]\ of\ Tcl,\ \"word\"\nlist\ as\ an\ \[abstract\ data\ type\].\ \ In\ the\ \[dodekalogue%|%rules\]\ of\ Tcl,\ \"word\"\nformat\ of\ a\ list.\ \ On\ this\ page,\ \"word\"\ is\ used\ in\ this\ technical\ sense\ to\nrefer\ specifically\ to\ a\ component\ of\ a\ string\ that\ represents\ a\ list.\ \ In\ other\nplaces\ it's\ used\ in\ the\ common\ non-technical\ sense.\ \ Enough\ context\ should\ be\nprovided\ to\ differentiate\ the\ two\ meanings.\ \n\n\n\n**\ Lists\ vs\ Commands\ **\n\nBecause\ both\ \[Dodekalogue%|%commands\]\ and\ lists\ use\ whitespace\ to\ delimit\nwords,\ every\ valid\ list\ is\ a\ valid\ script.\ \ However,\ not\ every\nwords,\ every\ valid\ list\ is\ a\ valid\ command.\ \ However,\ not\ every\nvalid\ command\ is\ a\ valid\ list:\n======\n%\ llength\ \{set\ b\ \[list\ \$one\ \"\$two\ \$three\"\]\}\nlist\ element\ in\ quotes\ followed\ by\ \"\]\"\ instead\ of\ space\n======\n\nThe\ `\]`\ at\ the\ end\ of\ the\ command\ is\ a\ violation\ of\ the\n'''\[Dodekalogue%|%double\ quotes\]'''\ rule,\ which\ states\ that\ `\"`\ terminates\ a\nquoted\ word.\ \ A\ space\ could\ be\ added\ to\ turn\ it\ into\ a\ well-formed\ list:\n\n======\n%\ llength\ \{set\ b\ \[list\ \$one\ \"\$two\ \$three\"\ \]\}\n6\n======\n\nNotice\ that\ although\ it\ is\ logically\ a\ three-word\ command,\ because\ of\n\[Dodekalogue%|%command\ substitution\]\ the\ last\ word\ in\ the\ command\ is\ actually\ncomposed\ of\ four\ words\ from\ the\ list.\n\n\n\n**\ Strings\ that\ Are\ Lists\ **\n\nAn\ empty\ string\ is\ an\ empty\ list:\n\n======\n%\ set\ list\ \[list\]\n%\ llength\ \$list\n0\n\n%\ set\ list\ \{\}\n%\ llength\ \$list\n0\n\n%\ set\ list\ \"\"\n%\ llength\ \$list\n0\n======\n\nA\ string\ containing\ nothing\ but\ whitespace\ is\ also\ an\ empty\ list:\n\n======\n%\ set\ list\ \{\ \}\n%\ llength\ \$list\n0\n\n%\ set\ list\ \\n\n%\ llength\ \$list\n0\n\nset\ list\ \\t\\n\\t\nllength\ \$list\ \;#\ ->\ 0\n======\n\nA\ string\ that\ contains\ no\ whitespace\ is\ often,\ but\ not\ always\ a\ list\ (containing\ one\ word):\n\n======\n%\ set\ list\ hello\n%\ llength\ \$list\n1\n\n%\ set\ list\ he\\\{llo\n%\ llength\ \$list\n1\n\n%\ set\ notalist\ \\\{hello\ \n%\ llength\ \$notalist\nunmatched\ open\ brace\ in\ list\n======\n\nThe\ following\ is\ a\ list\ that\ contains\ one\ word,\ which\ is\ an\ empty\ string:\n\n======\n%\ set\ list\ \{\{\}\}\n%\ llength\ \$list\n1\n\n%\ set\ list\ \[list\ \{\}\]\nllength\ \$list\ \;#\ ->\ 1\n======\n\nWhitespace\ separates\ words\ in\ a\ list:\n\n======\n%\ set\ list\ \{1\ 2\}\n%\ llength\ \$list\n2\n\n%\ set\ list\ \"1\ 2\"\n%\ llength\ \$list\n2\n======\n\nHere\ is\ a\ list\ that\ contains\ two\ words,\ both\ of\ which\ are\ empty\ strings:\n\n======\n%\ set\ list\ \{\{\}\ \{\}\}\n%\ llength\ \$list\n2\n======\n\n\nList\ commands\ parse\ strings\ into\ lists\ in\ much\ the\ same\ way\ that\ Tcl\ parses\nstrings\ into\ commands.\ \ In\ the\ following\ example,\ `\[llength\]`\ parses\ the\ string\ninto\ a\ list,\ and\ the\ backlash-space\ sequence\ results\ in\ the\ first\ character\ of\nthe\ second\ word\ being\ a\ space\ character:\n\n======\n%\ set\ list\ \{1\ \\\ 2\}\n%\ llength\ \$list\n2\n======\n\nIt\ is\ very\ common,\ and\ perfectly\ acceptable,\ to\ use\ braces\ instead\ of\ `list`\nwhen\ writing\ a\ list:\n\n======\n%\ set\ list\ \{one\ two\ three\}\n%\ llength\ \$list\n3\n======\n\nBut\ in\ Tcl,\ braces\ are\ simply\ a\ means\ of\ escaping\ whitespace\ and\ other\ special\ncharacters\ in\ strings.\ \ They\ are\ a\ nice\ way\ to\ write\ out\ lists,\ but\ Tcl\ itself\ndoesn't\ equate\ braces\ with\ lists.\ \ Any\ quoting\ can\ be\ used\ to\ make\ a\nwell-formed\ list,\ and\ there\ are\ an\ infinite\ number\ of\ ways\ to\ produce\ a\ string\nthat\ is\ the\ same\ well-formed\ list:\n\n======\n%\ set\ list\ \"one\ two\ three\"\n%\ llength\ \$list\n3\n\n%\ set\ list\ one\\\ two\\\ three\n%\ llength\ \$list\n3\n\n%\ set\ list\ one\\x20two\\x20three\n%\ llength\ \$list\n3\n\n%\ set\ list\ one\\ttwo\\tthree\\t\n%\ llength\ \$list\n3\n\n#...\ and\ on\ and\ on\ ...\n======\n\n\nWhen\ formatting\ a\ list\ as\ a\ string,\ `list`\ will\ escape\ values\ where\ necessary:\n\n======\n%\ list\ \\n\\\{\n\\n\\\{\n======\n\n\n\n**\ Strings\ that\ Are\ Not\ Lists\ **\n\n\[EIAS%|%All\ lists\ are\ strings\],\ but\ not\ all\ strings\ are\ well-formed\ lists.\ \ The\nvarious\ list\ commands\ expect\ their\ arguments\ to\ be\ well-formed\ lists.\n\n\nTo\ check\ whether\ a\ string\ is\ a\ list:\ \n\n======\nstring\ is\ list\ \$somevariable\n======\n\nAlternatively:\n\n======\ncatch\ \{llength\ \$somevariable\}\n======\n\nWhen\ doing\ experiments\ to\ understand\ lists,\ it\ is\ a\ good\ idea\ to\ first\ assign\nthe\ values\ in\ question\ to\ variables\ before\ operating\ on\ them,\ since\ it\ is\ hard\nto\ keep\ track\ of\ when\ quoting\ is\ interpreted\ as\ Tcl\ parses\ the\ command,\ \ and\nwhen\ the\ command\ is\ interpreting\ the\ values\ it\ has\ received\ as\ arguments.\ This\nmakes\ it\ possible\ to\ first\ inspect\ the\ value\ of\ the\ string\ before\ passing\ it\ to\na\ command:\n\n======\n%\ set\ var1\ \\\{\n\{\n======\n\nMany\ simple\ strings\ are\ lists:\n\n======\n%\ llength\ hello\n1\n%\ llength\ hello\\\ world\ \n2\n%\ llength\ \{how\ I\ made\ a\ great\ mistake\ in\ quotation\}\n8\n======\n\nSome\ strings,\ however,\ are\ '''not'''\ lists:\n\n======\n%\ llength\ \\\"\nunmatched\ open\ quote\ in\ list\n\n%\ llength\ \\\{\nunmatched\ open\ brace\ in\ list\n\n%\ llength\ \"ab\{\ \{x\ y\"\nunmatched\ open\ brace\ in\ list\n\n%\ llength\ \\\{\}a\nlist\ element\ in\ braces\ followed\ by\ \"a\"\ instead\ of\ space\n\n%\ llength\ \{\{a\ b\}\ \{c\}\]\}\nlist\ element\ in\ braces\ followed\ by\ \"\]\"\ instead\ of\ space\n\n%\ llength\ \{\{*\}exactitude\}\nlist\ element\ in\ braces\ followed\ by\ \"exactitude\"\ instead\ of\ space\n======\n\n\n\n**\ Canonical\ Representation\ **\n\nA\ single\ list\ may\ be\ represented\ by\ different\ combinations\ of\ double\ quotes,\ braces,\ and\nA\ single\ list\ may\ be\ represented\ by\ different\ of\ double\ quotes,\ braces,\ and\nbut\ the\ latter\ is\ the\ canonical\ representation\ of\ the\ list.\n\nTo\ produce\ the\ canonical\ representation\ of\ a\ list:\n\n======\nlist\ \{*\}\$somelist\n======\n\nOne\ quick\ and\ dirty\ way\ to\ check\ for\ list\ equality\ is\ to\ compare\ their\ncanonical\ representations\ as\ a\ string:\n\n======\nexpr\ \{\[list\ \{*\}\$list1\]\ eq\ \[list\ \{*\}\$list2\]\}\n======\n\nThis\ may\ be\ undesirable\ if\ the\ lists\ are\ large,\ because\ the\ string\ values\ of\nboth\ `\$list1`\ and\ `\$list2`\ are\ generated\ if\ they\ haven't\ been\ already.\n\nAnother\ thing\ `list\ \{*\}\$list1`\ does\ is\ armor\ special\ characters\ against\npossible\ interpretation\ if\ evaluated\ as\ a\ Tcl\ script:\n\n======\n%\ list\ \{*\}\{puts\ \$hello\;\ set\ b\ \[list\ \$one\ \$two\ \$three\]\}\nputs\ \{\$hello\;\}\ set\ b\ \{\[list\}\ \{\$one\}\ \{\$two\}\ \{\$three\]\}\n======\n\nIn\ other\ words,\ a\ list\ is\ formed\ such\ that\ the\ following\ is\ true\n(\[http://wiki.tcl.tk/440#pagetocad1fdaa5%|%1\]):\n\n======\nexpr\ \{\[eval\ list\ \$list\]\ eq\ \[list\ \{*\}\$list\]\}\n======\n\n\n\n**\ Using\ Braces\ to\ Write\ Lists\ **\n\nIn\ source\ code,\ braces\ are\ often\ used\ to\ write\ lists.\ \ One\ example\ is\ the\narguments\ to\ `\[proc\]`:\n\n======\nproc\ move\ \{element\ speed\ args\}\ ...\n======\n\nIt\ would\ be\ a\ bit\ awkward,\ and\ a\ bit\ slower,\ to\ use\ `list`\ for\ that:\n\n======\nproc\ move\ \[list\ element\ speed\ args\]\ ...\n======\n\nLikewise,\ literal\ braced\ strings\ are\ used\ with\ `\[switch\]`\ (in\ the\ braced\npatterns-and-bodies\ form),\ and\ `\[string\ map\]`\ (the\ map\ is\ a\ list).\ These\nbraced\ strings\ are\ usually\ not\ a\ problem,\ but\ you\ may\ need\ to\ think\ about\ list\ formatting\ when\ special\ characters\ (backslash,\ braces,\ whitespace,\ quotes)\ are\ninvolved.\ Sometimes,\ an\ extra\ layer\ of\ braces\ are\ required\ around\ a\ word\ in\ a\ list,\ but\ if\ it\ is\ unbalanced\ with\ respect\ to\ braces\ then\ you\ may\ need\ to\nbackslash-escape\ all\ special\ characters\ in\ it\ instead.\n\nBraces\ are\ also\ used\ to\ escape\ the\ body\ of\ a\ `\[proc\]`,\ but\ in\ that\ case,\ the\ body\ is\ not\ parsed\ as\ a\ list,\ but\ as\ a\ script\ (unescaped\ newlines\ take\ on\ special\ meaning):\n\n======\nproc\ myproc\ \{\}\ \{\n\ \ \ \ this\n\ \ \ \ is\ not\n\ \ \ \ parsed\ as\ a\ list,\n\ \ \ \ but\ as\ a\ script\n\}\n======\n\n\n**\ Generating\ Code\ **\n\nTcl\ is\ a\ dynamic\ language\ which\ allows\ for\ the\ construction\ of\ Tcl\ scripts\ at\nruntime.\ \ Since\ each\ command\ is\ a\ list,\ and\ a\ script\ is\ a\ sequence\ of\ lists,\nlist\ operations\ are\ often\ used\ to\ build\ up\ commands\ and\ scripts\ that\ can\ then\nbe\ interpreted\ using\ `\[eval\]`,\ `\[apply\]`\ and\ friends.\ \ When\ substituting\ some\npiece\ of\ information\ into\ the\ dynamically-generated\ script,\ it\ is\ usually\nnecessary\ to\ subtitute\ in\ a\ list,\ even\ if\ the\ context\ requires\ a\ single\ value.\n\[string\ map\]\ is\ can\ be\ used\ for\ this\ purpose.\n\n----\n\n\[KBK\]\ writes\ on\ comp.lang.tcl\ (with\ some\ modifications):\n\nIf\ a\ string\ has\ been\ built\ up\ using\ the\ list\ commands,\ for\ instance\ `\[list\]`\ and\n`\[lappend\]`,\ then\ it\ is\ always\ well-formed\ as\ a\ command.\ \ The\ first\ word\ of\nthe\ list\ (word\ number\ zero)\ will\ be\ the\ command\ name\ and\ the\ remaining\nwords\ will\ be\ what\ the\ command\ sees\ as\ its\ parameters.\ \ This\ method,\ in\nfact,\ is\ one\ of\ only\ a\ very\ few\ ways\ to\ construct\ command\ strings\ that\ have\ the\ndesired\ parameters\ when\ one\ or\ more\ of\ the\ parameters\ contains\ user-supplied\ndata,\ possibly\ including\ nasties\ like\ backslashes\ or\ unbalanced\ braces.\n\nIn\ particular,\ using\ double-quotes\ and\ the\ string\ commands\ such\ as\ `\[append\]`\nand\ `\[subst\]`\ is\ NOT\ safe\ for\ constructing\ command\ strings\ with\ arbitrary\ data.\n\nMoreover,\ `\[eval\]`\ and\ its\ friends\ give\ you\ special\ support\ for\ the\ technique\nof\ using\ lists\ as\ commands.\ \ If\ a\ command\ being\ evaluated\ is\ a\ \"pure\"\ list,\nthat\ is,\ one\ that\ was\ constructed\ using\ the\ list\ commands\ and\ has\ never\nacquired\ a\ string\ representation,\ then\ the\ evaluator\ is\ able\ to\ short-circuit\nthe\ parsing\ process,\ knowing\ that\ all\ arguments\ have\ been\ substituted.\ \ It\ndoesn't\ need\ to\ do\ the\ (fairly\ expensive)\ scan\ for\ \$-\ \[\]-\ and\ \\-\ substitution,\nnor\ balance\ \"\"\ and\ \{\},\ but\ can\ go\ directly\ to\ looking\ up\ the\ command\ name\ and\ninvoking\ it.\n\n\n\n\n**\ Using\ List\ to\ Concatenate\ Lists\ **\n\n`list`\ can\ be\ used\ with\ \[\{*\}\]\ to\ the\ same\ effect\ as\ `\[concat\]`:\n\n======\nset\ a\ \{a\ b\ c\}\;\ set\ b\ \{d\ e\ f\}\nlist\ \$a\ \$b\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ ->\ \{a\ b\ c\}\ \{d\ e\ f\}\nconcat\ \$a\ \$b\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ ->\ a\ b\ c\ d\ e\ f\nlist\ \{*\}\$a\ \{*\}\$b\ \ \ \ \ \ \ \ \ \ \ \ \ \ \;#\ ->\ a\ b\ c\ d\ e\ f\n======\n\nSee\ \[Concatenating\ lists\]\ for\ a\ timing\ comparison\ of\ the\ various\ methods.\n\n\n\n**\ \ Concatenating\ Lists\ **\n\nThe\ following\ three\ methods\ for\ concatenating\ list\ are\ roughly\ equivalent\ in\nperformance:\n\n======\nset\ list\ hello\nconcat\ \$list\ \$list\nlist\ \{*\}\$list\ \{*\}\$list\nlappend\ list\ \{*\}\$list\n======\n\nThe\ difference\ is\ that\ `\[concat\]`\ does\ not\ make\ sure\ its\ arguments\ are\ valid\nlists,\ and\ `\[lappend\]`\ modifies\ `\$list`\n\nBefore\ the\ advent\ of\ the\ \[\{*\}\]\ operator,\ the\ following\ syntax\ was\ used:\n\n======\neval\ \[list\ lappend\ baseList\]\ \$extraList\n======\n\n\n\n**\ Newline-delimited\ Lists\ **\n\nWhen\ writing\ a\ list\ of\ lists\ to\ a\ file,\ it's\ useful\ to\ represent\ it\ using\ the\nnewline\ character\ to\ separate\ the\ words\ of\ the\ lists.\ \ Here's\ how\ to\ do\ that:\n\n======\nforeach\ list\ \$tosave\ \{\n\ \ \ \ puts\ \$chan\ \\\{\n\ \ \ \ foreach\ word\ \$list\ \{\n\ \ \ \ \ \ \ \ puts\ \$chan\ \[list\ \$word\]\n\ \ \ \ \}\n\ \ \ \ puts\ \$chan\ \\\}\n\ \ \ \ puts\ \$chan\ \{\}\n\}\n======\n\nThe\ result\ is\ a\ list\ of\ lists,\ having\ the\ same\ length\ as\ `\$tosave`.\n\n\n\n**\ Internal\ Structured\ Representation\ **\n\n\nInternally,\ Tcl\ tracks\ the\ structure\ of\ the\ list,\ and\ the\ various\ list\ commands\ntake\ advantage\ of\ this\ to\ improve\ performance\ to\ O(1)\ time\ (access\ time\ does\nnot\ depend\ on\ the\ total\ list\ length\ or\ position\ within\ the\ list).\ \ A\ string\nrepresentation\ of\ a\ list\ is\ not\ made\ until\ is\ is\ needed.\ \ Therefore,\ \na\ `\[string\]`\ operation\ on\ a\ large\ list\ may\ incur\ a\ dramatic\ performance/storage\npenalty\ if\ it\ causes\ the\ string\ representation\ has\ to\ be\ generated.\ \ The\ rule\ of\ of\ thumb\nis\ to\ use\ list-aware\ commands\ for\ lists,\ and\ avoid\ string\ commands.\ \ One\ obvious\ exception\ to\ this\ rule\ is\ `\[string\ is\ list\]`,\ which\ is\ smart\ enough\ not\ to\ generate\ the\ string\ representation\ of\ a\ pure\ list.\n\n`\[concat\]`\ is\ a\ string\ operation,\ but\ is\ smart\ enough\ not\ to\ incur\ the\npenalty\ if\ all\ its\ arguments\ are\ pure\ lists.\n\nThe\ internal\ representation\ of\ a\ list\ should\ be\ transparent\ at\ the\ script\nlevel,\ but\ for\ the\ curious:\n\nIn\ the\ \[C\]\ implementation\ of\ Tcl\ 8.x,\ a\ list\ is\ a\ type\ of\ \[Tcl_Obj\],\ \ The\nelements\ of\ a\ list\ are\ stored\ as\ C-style\ vectors\ of\ pointers\ to\ the\ individual\n\[Tcl_Obj\]\ element\ values,\ plus\ some\ extra\ data.\ \ The\ consequence\ of\ this\ is\nthat\ `\[llength\]`\ and\ `\[lindex\]`\ are\ constant-time\ operations\ —\ they\ are\nas\ fast\ for\ large\ lists\ as\ they\ are\ for\ small\ lists.\n\n\n\n**\ `\[concat\]`\ **\n\ \ \ \n`\[concat\]`\ also\ operates\ on\ lists,\ but\ does\ not\ require\ that\ its\ arguments\nbe\ valid\ lists.\ `\[foreach\]`\ operates\ on\ lists.\ \ `\[split\]`\ creates\ lists,\nand\ `\[join\]`\ consumes\ them.\ \ Various\ other\ commands\ also\ make\ use\ of\ lists.\n\nSince\ all\ values,\ including\ lists,\ \[EIAS%|%are\ strings\]\ (but\ not\ all\ strings\ are\ lists!),\ it\ is\ possible\ to\ use\ `\[string\]`\ commands\ on\nlists,\ but\ performance\ can\ suffer\ and\ there\ are\ usually\ better\ ways\ to\naccomplish\ the\ task.\ \ In\ some\ common\ cases,\ Tcl\ is\ smart\ enough\ to\ do\ the\ right\ thing.\ \ For\ example,\ doing\ a\ string\ comparision\ between\ a\ list\ and\ the\ empty\ string\ is\ perfectly\ acceptable,\ and\ just\ as\ performant\ as\ the\ `\[llength\]`\ variant:\n\n======\nproc\ foo\ \{bar\ args\}\ \{\n\ \ \ \ if\ \{\$args\ eq\ \{\}\}\ then\ \{\ #string\ comparison\ might\ force\ internal\ Tcl\ gyrations\n\ \ \ \ \ \ \ \ set\ args\ \$::foo::default_for_args\n\ \ \ \ \}\n\ \ \ \ #\ ...\n\}\n======\n\nThe\ `\[llength\]`\ variant:\n\n======\nproc\ foo\ \{bar\ args\}\ \{\n\ \ \ \ if\ \{\[llength\ \$args\]\ ==\ 0\}\ then\ \{\ #\ \$args\ is\ empty\n\ \ \ \ \ \ \ \ set\ args\ \$::foo::default_for_args\n\ \ \ \ \}\n\ \ \ \ #\ ...\n\}\n======\n\n\n**\ Layers\ of\ Interpretation\ **\n\nIn\ the\ following\ example,\ the\ value\ of\ `a_single_backslash`\ is\ a\ single\ backslash:\n\n======\nset\ a_single_backslash\ \[lindex\ \\\\\\\\\ 0\]\n======\n\nprior\ to\ evaluating\ the\ lindex\ command,\ Tcl\ performs\ backslash\ substitution\ on\nthe\ four\ backslashes,\ so\ that\ the\ first\ argument\ becomes\ two\ backslashes.\ \ To\nconvert\ the\ first\ argument\ to\ a\ list,\ the\ `\[lindex\]`\ command\ then\ performs\nbackslash\ on\ substitution\ on\ the\ two\ backslashes,\ resulting\ in\ one\ backslash,\nwhich\ is\ then\ assigned\ to\ `a_single_backslash`.\n\n\n\n**\ Converting\ a\ String\ to\ a\ List\ **\n\n`\[split\]`\ takes\ a\ string\ and\ returns\ a\ list,\ but\ the\ best\ choice\ depends\ on\nthe\ task\ at\ hand.\ `\[regexp\]`\ is\ often\ handy:\n\n======\nset\ wordList\ \[regexp\ -all\ -inline\ \{\\S+\}\ \$myGnarlyString\]\n======\n\n\n\[DKF\]\ proposed\ this\ pretty\ alias:\n\n======\ninterp\ alias\ \{\}\ listify\ \{\}\ regexp\ -all\ -inline\ \{\\S+\}\n======\n\ \n\[Bill\ Paulson\]\ notes\ that\ this\ alias\ changes\ all\ white\ space\ to\ a\ single\ space,\ \nwhich\ might\ or\ might\ not\ be\ what\ you\ want.\n\nOther\ than\ that,\ this\ '''listify'''\ is\ effectively\ a\ `\[split\]`\ that\ interprets\ adjacent\ delimiters\ as\ as\ a\ single\ delimiter\ rather\ than\ interpreting\ them\ as\ delimiting\ an\ empty\ string,\ like\ `\[split\]`\ does.\n\n\n(2014-09-08):\ this\ can\ also\ be\ used\ to\ duplicate\ words\ in\ a\ list:\n\[PL\]\ (2014-09-08):\ this\ can\ also\ be\ used\ to\ duplicate\ words\ in\ a\ list:\n======\nregexp\ -all\ -inline\ \{\\S+\}\ \{a\ b\ c\}\n#\ =>\ a\ b\ c\nregexp\ -all\ -inline\ \{(\\S+)\}\ \{a\ b\ c\}\n#\ =>\ a\ a\ b\ b\ c\ c\nregexp\ -all\ -inline\ \{((\\S+))\}\ \{a\ b\ c\}\n#\ =>\ a\ a\ a\ b\ b\ b\ c\ c\ c\n======\n\netc.\n\n\n**\ Validating\ a\ List\ **\n\nVarious\ ways\ to\ check\ whether\ a\ string\ is\ a\ list:\n\n======\nstring\ is\ list\ \$some_value\ncatch\ \{lindex\ \$some_value\ 0\}\ncatch\ \{llength\ \$some_value\}\n======\n\nIn\ later\ versions\ of\ Tcl,\ \[string\ is\ list\]\ is\ available.\n\n\n\n**\ List\ Vs.\ List\ of\ Lists\ **\n\n\[escargo\]\ 2003-03-16:\ How\ can\ you\ tell\ if\ a\ value\ is\ a\ string\ of\ words\ '''or'''\na\ list\ of\ strings\ of\ words?\n\nThe\ practical\ application\ that\ I\ had\ for\ this\ was\ an\ error-printing\ proc.\ It\ncould\ be\ passed\ a\ value\ that\ might\ be\ a\ single\ error\ message\ or\ a\ list\ of\ error\nmessages.\ \ If\ it\ were\ a\ single\ error\ message,\ then\ I\ could\ print\ it\ on\ one\nline\;\ if\ it\ were\ multiple\ messages,\ then\ I\ wanted\ to\ print\ each\ on\ its\ own\nline.\n\nSo,\ how\ could\ I\ distinguish\ between\ the\ cases?\n\nI\ think\ I\ eventually\ made\ all\ sources\ of\ errors\ provide\ a\ list\ of\ errors,\ even\nif\ was\ always\ a\ list\ of\ 1\ (instead\ of\ just\ the\ error\ message\ string).\n\nBut\ the\ question\ always\ stuck\ with\ me?\ \ Was\ there\ a\ way\ I\ could\ have\ easily\ndistinguished\ between\ the\ two?\ \ Could\ I\ look\ at\ the\ representation\ and\ see\ an\nopening\ curly\ brace\ if\ it\ were\ a\ list?\n\n\[RS\]:\ The\ (outer)\ curlies\ are\ not\ part\ of\ the\ list\ -\ they\ are\ added,\ or\ parsed\naway,\ when\ needed.\n\nTcl\ \[list\]s\ are\ not\ fundamentally\ different\ from\ strings,\ rather,\ I'd\ say\ they\nare\ a\ \"view\"\ on\ strings.\ Just\ as\ `42`\ can\ be\ viewed\ as\ string,\ or\ integer,\ it\ncan\ also\ be\ viewed\ as\ a\ one-word\ list.\ Except\ if\ you\ introduce\ your\ own\ntagging\ convention,\ there\ is\ no\ way\ of\ telling\ whether\ a\ list\ is\ in\ reality\ a\nstring\ -\ in\ the\ other\ direction,\ only\ strings\ that\ cannot\ be\ parsed\ as\ lists\n(unbalanced\ braces,\ quotes..)\ cannot\ be\ viewed\ as\ lists.\ But\ for\ your\ concrete\nerror-printing\ problem:\ if\ you\ simplify\ the\ interface\ to\ \"a\ list\ of\ one\ or\ more\nerror\ messages\",\ you\ can\ have\ the\ desired\ effect\ with\n\n======\nputs\ \[join\ \$errormessages\ \\n\]\n======\n\nJust\ make\ sure\ that\ the\ \"one\ message\"\ case\ is\ properly\ nested,\ e.g.\n\n======\nerrorprint\ \{\{This\ is\ a\ one-liner\}\}\nerrorprint\ \"\{This\ too,\ with\ a\ \$variable\ reference\}\"\ \;#\ braces\ in\ quoted\ strings\ allow\ substitution\nerrorprint\ \[list\ \"another\ \$variable\ reference\"\]\nerrorprint\ \{\{Two\ messages:\}\ \{This\ is\ the\ second\}\}\n======\n\n\n\n**\ Single-word\ Lists\ vs\ non-list\ value\ **\n\nMany\ simple\ string\ values\ can\ also\ be\ interpreted\ as\ single-word\ lists.\nPrograms\ should\ use\ additional\ data\ or\ rely\ on\ program\ logic\ to\ decide\ whether\na\ value\ should\ be\ interpreted\ as\ a\ list\ or\ a\ string.\n\nHere\ is\ another\ way\ of\ looking\ at\ the\ problem\ (`\[lindex\]`\ without\ an\ index\nreturns\ the\ list\ argument\ unchanged):\n\n======\n%\ lindex\ a\na\n%\ lindex\ a\ 0\na\n%\ lindex\ \[lindex\ a\ 0\]\ 0\na\n%\ lindex\ \[lindex\ \[lindex\ a\ 0\]\ 0\]\ 0\na\n%\ lindex\ \{a\}\na\n%\ lindex\ \{a\}\ 0\na\n%\ lindex\ \[lindex\ \{a\}\ 0\]\ 0\na\n%\ lindex\ \[lindex\ \[lindex\ \{a\}\ 0\]\ 0\]\ 0\na\n%\ lindex\ \{\{a\}\}\n\{a\}\n%\ lindex\ \{\{a\}\}\ 0\na\n%\ lindex\ \[lindex\ \{\{a\}\}\ 0\]\ 0\na\n%\ lindex\ \[lindex\ \[lindex\ \{\{a\}\}\ 0\]\ 0\]\ 0\na\n%\ lindex\ \{\{\{a\}\}\}\n\{\{a\}\}\n%\ lindex\ \{\{\{a\}\}\}\ 0\n\{a\}\n%\ lindex\ \[lindex\ \{\{\{a\}\}\}\ 0\]\ 0\na\n%\ lindex\ \[lindex\ \[lindex\ \{\{\{a\}\}\}\ 0\]\ 0\]\ 0\na\n======\n\nNo\ program\ can\ tell\ the\ difference\ between\ the\ string\ \"a\"\ and\ the\ one-word\nlist\ \"a\",\ because\ the\ one-word\ list\ \"a\"\ ''is''\ the\ string\ \"a\".\n\n\[Dossy\]\ 2004-02-26:\ A\ co-worker\ yesterday\ who\ is\ new\ to\ Tcl\ discovered\nsomething\ that\ surprised\ me\ --\ \[nested\ list\]s\ in\ Tcl\ don't\ work\ as\ I\ expected\nin\ a\ very\ specific\ case:\n\n======\n%\ list\ \[list\ \[list\ x\]\]\nx\n======\n\nUm,\ when\ I\ ask\ for\ a\ list\ of\ a\ list\ of\ a\ list\ with\ the\ single\ word\ 'x',\ I\nwould\ expect\ '\{\{\{x\}\}\}'\ back.\ \ However,\ you\ just\ get\ 'x'\ back.\ \ Thinking\ about\nit,\ I\ understand\ why,\ but\ it\ means\ that\ Tcl\ lists\ alone\ cannot\ be\ used\ to\nrepresent\ ALL\ kinds\ of\ data\ structures,\ as\ Tcl\ lists\ magically\ collapse\ when\nit's\ a\ series\ of\ nested\ lists\ with\ the\ terminal\ list\ having\ only\ a\ single\nbare\ word\ that\ requires\ no\ escaping.\n\n\[Lars\ H\]:\ It\ looks\ worse\ than\ it\ is.\ For\ one\ thing,\ it\ is\ only\ the\ string\nrepresentation\ that\ collapses,\ not\ the\ internal\ representation,\ so\ the\ above\nnesting\ of\ `list`\ is\ not\ completely\ pointless.\ It\ is\ furthermore\ very\nuncommon\ (and\ this\ is\ ''not''\ specific\ to\ Tcl)\ that\ nesting\ depth\ alone\ has\ a\nsignificance.\ Either\ you\ know\ the\ structure\ of\ the\ value,\ and\ thereby\ the\nintended\ nesting\ depth,\ or\ the\ list\ is\ some\ generic\ \"thing\",\ and\ in\ that\ case\nyou\ anyway\ need\ a\ label\ specifying\ what\ kind\ of\ thing\ it\ is.\n\n\[DBaylor\]:\ I\ think\ this\ is\ actually\ worse\ than\ it\ looks.\ \ I\ see\ lots\ of\ people\ntrying\ to\ learn\ Tcl\ and\ the\ #1\ point\ of\ confusion\ is\ Dossy's\ example.\ \ But\ what\nI\ really\ dislike\ about\ this\ behavior\ is\ that\ it\ hides\ bugs\ until\ specific\ input\nis\ encountered.\ \ If\ you\ ever\ mix\ up\ your\ data-types\ (string\ vs.\ list),\ your\ncode\ will\ work\ fine\ 99%\ of\ the\ time\ -\ until\ special\ characters\ are\ involved.\nThese\ bugs\ are\ inevitably\ found\ the\ hard\ way.\ \ Oh\ how\ I\ wish\ `\[list\]\ x`\nreturned\ `\{x\}`.\n\n\[PYK\]\ 2013-10-27:\ What\ would\ `\[lindex\]\ x\ 0`\ return,\ then?\ \ An\ error\ that\ `x`\nis\ not\ a\ list?\ \ All\ commands\ are\ lists\ (after\ adjusting\ for\ \[Dodekalogue%|%command\ substitution\]),\ and\ `x`\ is\ potentially\ a\ valid\ command.\nTherefore,\ `x`\ must\ be\ a\ list.\ \ There\ is\ some\ subtlety\ to\ Tcl\ which\ can\ take\ a\nlittle\ time\ for\ beginners\ to\ wrap\ their\ heads\ around,\ but\ this\ subtlety\ is\nTcl's\ strength,\ not\ its\ weakness.\ \ The\ gripe\ about\ hiding\ bugs\ until\ specific\ninputs\ are\ encountered\ is\ a\ gripe\ about\ dynamic\ languages\ in\ general,\ and\ not\nparticular\ at\ all\ to\ Tcl.\n\n\n\n**\ Subsetting\ a\ List\ **\n\n\[LV\]\ Question:\ in\ \[Perl\],\ \[Python\],\ and\ a\ number\ of\ other\ languages,\ one\ has\nthe\ ability\ to\ read\ and\ write\ to\ subsets\ of\ a\ list\ --\ ''slices''\ --\ using\ an\nalmost\ array\ like\ notation.\ \ Is\ this\ something\ that\ one\ could\ simulate\ without\nmuch\ grief\ in\ Tcl?\n\ \n\[RS\]:\ But\ of\ course\ -\ our\ old\ friends\ (with\ wordier\ notation)\n\n======\nset\ slice\ \[lrange\ \$list\ \$from\ \$to\]\nset\ newlist\ \[eval\ lreplace\ \[list\ \$otherlist\]\ \$from\ \$to\ \$slice\]\n======\n\n`\[lset\]`\ can\ only\ replace\ a\ single\ element,\ but\ possibly\ several\ layers\ deep\nin\ the\ nesting.\ For\ reading\ access\ to\ a\ slice\ of\ a\ list,\ check\ \[Salt\ and\ sugar\]\nfor\ how\ the\ following\ is\ implemented:\n\n======\nset\ i\ \[\$\ \{a\ b\ c\ d\ e\ f\ g\}\ 2\ 4\]\ ==>\ \{c\ d\ e\}\n======\n\n\n\n**\ Flattening\ a\ List\ **\n\nTo\ flatten\ a\ list:\n\n======\nconcat\ \{*\}\$nested\n======\n\nIt\ can\ be\ applied\ multiple\ times:\n\n======\nproc\ flatten\ data\ \{\n\ \ \ \ concat\ \{*\}\$data\n\}\nset\ a\ \{\{a\ \{b\ c\}\}\ \{d\ \{e\ f\}\}\}\ \ \;\ #\ \{a\ \{b\ c\}\}\ \{d\ \{e\ f\}\}\nflatten\ \$a\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \;\ #\ a\ \{b\ c\}\ d\ \{e\ f\}\nflatten\ \[flatten\ \$a\]\ \ \ \ \ \ \ \ \ \;\ #\ a\ b\ c\ d\ e\ f\n======\n\nalternatively:\n\n======\nset\ flattened\ \[join\ \$mylist\]\n======\n\nAnother\ possibility:\n\n======\nforeach\ e\ \$list\ \{\n\ \ \ \ foreach\ ee\ \$e\ \{\n\ \ \ \ \ \ \ \ lappend\ flatList\ \$ee\n\ \ \ \ \}\n\}\n======\n\n`\[eval\]`\ is\ not\ a\ good\ option\ because\ it\ chokes\ on\ newlines:\n\n======\n%\ eval\ concat\ \{a\nb\}\nambiguous\ command\ name\ \"b\":\ binary\ break\n======\n\nThe\ newline\ in\ the\ argument\ ends\ `\[concat\]`\ and\ starts\ a\ new\ command.\ This\ is\ndue\ neither\ to\ `\[concat\]`\ nor\ to\ the\ \[tclsh\]\ prompt\ loop,\ but\ to\ the\ nature\nof\ `\[eval\]`.\n\nTo\ get\ around\ that\ issue,\ first\ pass\ the\ value\ through\ a\ command\ that\ parses\nstrings\ into\ valid\ lists:\n\n======\neval\ concat\ \[lrange\ \{a\nb\n\}\ 0\ end\]\n======\n\n\n\[RS\]\ 2004-02-26:\ If\ you\ really\ want\ to\ flatten\ a\ list\ of\ any\ depth,\ \ni.e.\ remove\ all\ grouping,\ I\ think\ this\ way\ is\ simplest\ (and\ robust):\n\n======\nproc\ flatten\ list\ \{\n\ \ \ \ string\ map\ \{\\\{\ \"\"\ \\\}\ \"\"\}\ \$list\n\}\n%\ flatten\ \{a\ \{b\ \{c\ d\ \{e\ f\ \{g\ h\}\}\}\}\}\na\ b\ c\ d\ e\ f\ g\ h\n======\n\n\[Lars\ H\]:\ No,\ that\ won't\ work.\ Consider\n\n======\n%\ flatten\ \[list\ \\\{\ \\\}\]\n\\\ \\\n======\n\nI'd\ give\ you\ that\ it\ isn't\ exactly\ clear\ what\ should\ happen\ to\ lists\ with\ such\nwords,\ but\ the\ above\ doesn't\ get\ a\ single\ character\ right.\n\n\[RS\]\ admits\ he\ was\ thinking\ of\ well-behaved\ lists\ (as\ built\ with\ `\[list\]`\nand\ `\[lappend\]`,\ where\ braces\ are\ only\ generated\ mark-up,\ not\ content\ :^)\nYou're\ right\ to\ point\ out\ that\ ''flatten''\ is\ not\ chimpanzee-proof,\ and\ robust,\nenough.\n\n\[cyrilroux\]\ 2010-10-28:\ \ Maybe\ here\ is\ the\ solution\ to\ solve\ the\ escape\ issue?\nThis\ always\ consist\ in\ replacing\ all\ \{\ and\ \}\ but\ NOT\ \\\{\ and\ \\\}\ (escaped\ ones).\nThat\ is\ to\ say\ 6\ cases:\n\n\"^\{\"\n\"\ \{\"\n\"\{\{+\"\n\"\}\$\"\n\"\}\ \"\n\"\}\}+\"\n\n======\nproc\ lflatten\ list\ \{\n\ \ \ \ regsub\ -all\ \{^\\\{|\ \\\{|\\\{\\\{+|\\\}\$|\\\}\ |\\\}\\\}+\}\ \$list\ \{\ \}\ flatten\n\ \ \ \ return\ \$flatten\n\}\n\n%\ set\ foo\ \{\{a\ \{b\ c\}\}\ \{d\\\{d\\\{\ \{e\ f\}\ g\}\}\n%\ lflatten\ \$foo\na\ b\ c\ \ d\{d\{\ e\ f\ g\ \n======\n\n\n\[CMP\]:\ In\ general,\ string\ manipulation\ on\ lists\ all\ have\ the\ same\ problem\;\ they\ndo\ not\ consider\ the\ list\ structure\ (unless\ copying\ the\ complete\ implementation\nof\ the\ existing\ list\ commands).\ \ Hence,\ all\ list\ manipulations\ should\ be\ done\nusing\ existing\ list\ commands.\n\n\n\n**\ Information\ about\ struct::list\ -\ extended\ list\ operations\ **\n\n\[Tcllib\]\ now\ contains\ a\ \[struct::list\]\ module.\ \ Its\ documentation\ can\ be\ found\nat\ http://tcllib.sourceforge.net/doc/struct_list.html.\n\n\[dgp\]\ offers\ this\ example\ of\ making\ use\ of\ it:\n\n\n======\n%\ package\ require\ struct\ 1.3\n1.3\n%\ namespace\ eval\ my\ \{\n\ \ \ \ namespace\ import\ ::struct::list\n\ \ \ \ set\ l\ \[::list\ 1\ 2\ 3\]\n\ \ \ \ puts\ \[list\ reverse\ \$l\]\n\}\n3\ 2\ 1\n======\n\nMore\ explanation…\n\nIn\ the\ above\ example,\ is\ the\ use\ of\ ''::list''\ in\ the\ set\ command\ vs\ ''list''\ in\ the\ \n\[puts\]\ command\ merely\ an\ example\ of\ different\ ways\ of\ referring\ to\ portions,\ or\ does\ one\nrefer\ to\ the\ original\ tcl\ list\ versus\ the\ imported\ new\ list\ command?\n\n\[MG\]\ I\ believe\ ''::list''\ in\ the\ above\ refers\ to\ the\ Tcl\ list\ command,\ and\n''list''\ refers\ to\ the\ imported\ ''::struct::list''\ (which\ is\ then\ also\n''::my::list'',\ as\ it's\ imported).\ \ Or\ at\ least\ I\ think\ that's\ right.\nNamespaces\ used\ like\ that\ require\ a\ lot\ more\ sleep\ than\ I've\ had\ lately\ \;)\n\n\n\n**\ What\ would\ a\ Tcl\ version\ of\ the\ list\ command\ look\ like?\ **\n\n\[AMG\]:\ Is\ this\ an\ acceptable\ implementation\ of\ `list`?\n\n======\nproc\ list\ args\ \{\n\ \ \ \ return\ \$args\n\}\n======\n\nLooks\ right\ to\ me...\n\n\[RS\]:\ To\ me\ too.\ That's\ because\ ''args''\ is\ already\ a\ list,\ as\ by\ the\ Tcl\nparser...\ I'd\ just\ write\n\n\n======\nproc\ list\ args\ \{set\ args\}\n======\n\n\[AMG\]:\ Chuckle.\n\n======\nproc\ list\ args\ \[list\ set\ args\]\n======\n\n\n\n**\ Transform\ a\ list\ into\ a\ list\ of\ fixed\ size\ lists\ **\n\n\[LV\]:\ \ in\ response\ to\ a\ question,\ Jonathan\ Bromley,\ 2008-05-30,\n\[comp.lang.tcl\],\ wrote\ the\ following\ Tcl\ proc\ for\ turning\ a\ long\ list\ into\ a\nlist\ of\ lists:\n\n======\nproc\ split_list\ \{L\ \{n\ 50\}\}\ \{\ \n\ \ \ \ incr\ n\ 0\;\ #\ thanks\ to\ RS\ for\ this\ cool\ \"is\ it\ an\ int\"\ check!\ \n\ \ \ \ set\ result\ \{\}\ \n\ \ \ \ set\ limit\ \[expr\ \{\[llength\ \$L\]\ -\ \$n\}\]\ \n\ \ \ \ for\ \{set\ p\ 0\}\ \{\$p\ <=\ \$limit\}\ \{incr\ p\ \$n\}\ \{\ \n\ \ \ \ \ \ \ \ lappend\ result\ \[lrange\ \$L\ \$p\ \[expr\ \{\$p+\$n-1\}\]\]\ \n\ \ \ \ \}\ \n\ \ \ \ return\ \$result\ \n\}\ \n======\n\n\[arg\]:\ \ Just\ the\ code\ I\ wanted\ (needed\ to\ split\ results\ from\ SQLite).\ Thanks.\nBut\ can\ I\ suggest\ a\ few\ tweaks:-\n\n\ \ \ 1.\ name\ changed\ to\ \"partitionlist\",\ I\ think\ it's\ less\ ambiguous\ than\ \"split_list\".\ Any\ ideas\ for\ a\ better\ name?\n\ \ \ 2.\ change\ default\ from\ 50\ to\ 2,\ splitting\ into\ pairs\ looks\ a\ more\ useful\ default.\n\ \ \ 3.\ change\ setting/comparing\ \"limit\"\ so\ that\ all\ the\ elements\ of\ the\ original\ list\ are\ copied,\ the\ original\ version\ acted\ as\ if\ the\ original\ list\ were\ truncated\ to\ a\ multiple\ of\ the\ requested\ sublist\ length.\ This\ version\ will\ output\ any\ \"extra\"\ elements\ as\ another\ short\ sublist.\n\n======\nproc\ partitionlist\ \{L\ \{n\ 2\}\}\ \{\ \n\ \ \ \ incr\ n\ 0\;\ #\ thanks\ to\ RS\ for\ this\ cool\ \"is\ it\ an\ int\"\ check!\ \n\ \ \ \ set\ result\ \{\}\ \n\ \ \ \ set\ limit\ \[llength\ \$L\]\ \n\ \ \ \ for\ \{set\ p\ 0\}\ \{\$p\ <\ \$limit\}\ \{incr\ p\ \$n\}\ \{\ \n\ \ \ \ \ \ \ \ lappend\ result\ \[lrange\ \$L\ \$p\ \[expr\ \{\$p+\$n-1\}\]\]\ \n\ \ \ \ \}\ \n\ \ \ \ return\ \$result\ \n\}\ \n======\n\n\[Lars\ H\]:\ If\ the\ partitioned\ list\ is\ then\ immediately\ going\ to\ be\ iterated\nover,\ it\ may\ of\ course\ be\ easier\ to\ take\ advantage\ of\ the\ fact\ that\ the\nvariable\ arguments\ of\ \[foreach\]\ are\ really\ lists\ of\ variables.\ I.e.,\ instead\ of\n\n======\nforeach\ row\ \[partitionlist\ \$data\ 3\]\ \{\n\ \ \ \ lassign\ \$row\ first\ second\ third\n\ \ \ \ #\ Further\ processing...\n\}\n======\n\none\ can\ just\ do\n\n======\nforeach\ \{first\ second\ third\}\ \$data\ \{\n\ \ \ \ #\ Further\ processing...\n\}\n======\n\nConversely,\ this\ can\ be\ used\ for\ the\ following\ \[braintwisters\]'\ implementation\ of\ '''partitionlist''':\n\n======\nproc\ partitionlist\ \{L\ \{n\ 2\}\}\ \{\n\ \ \ \ set\ varlist\ \{\}\n\ \ \ \ set\ body\ \{lappend\ res\ \[list\}\n\ \ \ \ for\ \{\}\ \{\$n>0\}\ \{incr\ n\ -1\}\ \{\n\ \ \ \ \ \ \ \ lappend\ varlist\ \$n\n\ \ \ \ \ \ \ \ append\ body\ \{\ \$\}\ \$n\n\ \ \ \ \}\n\ \ \ \ set\ res\ \{\}\n\ \ \ \ foreach\ \$varlist\ \$L\ \[append\ body\ \\\]\]\n\ \ \ \ return\ \$res\n\}\n======\n\n\n**\ Other\ uses\ of\ `\[list\]`\ **\n\n\[AMG\]:\ When\ given\ no\ arguments,\ `\[list\]`\ returns\ empty\ string.\ \ I\ find\ this\nuseful\ when\ entering\ Tcl\ commands\ interactively,\ e.g.\ into\ \[tkcon\]\ or\ \[tclsh\].\nWhen\ I\ know\ that\ a\ command\ will\ produce\ a\ lot\ of\ output,\ such\ as\n`\[read\]`'ing\ a\ whole\ file,\ and\ I\ don't\ want\ to\ have\ it\ all\ on\ my\ screen,\ I\ntack\ \"\;\ list\"\ onto\ the\ end\ of\ my\ command\ line.\n\n======\n\$\ tclsh\n%\ set\ chan\ \[open\ bigfile\]\nfile12dcd00\n%\ set\ data\ \[read\ \$chan\]\;\ list\n%\ close\ \$chan\n======\n\nIf\ not\ for\ the\ `\;\ list`,\ the\ second\ line\ would\ flood\ my\ terminal\ with\ lots\ and\nlots\ of\ garbage.\n\n\[AMG\]:\ Another\ use\ for\ list\ is\ to\ pass\ it\ a\ single\ argument\ which\ it\ will\ then\nreturn.\ \ For\ an\ example,\ see\ SCT\ &\ \[RS\]'s\ comments\ on\ the\ page\ for\ `\[if\]`.\nHowever,\ this\ works\ due\ to\ the\ \"problem\"\ noted\ above\ by\ \[Dossy\]\ 2004-02-26.\nOften\ the\ argument\ requires\ quoting\ to\ become\ a\ single-word\ list,\ in\ which\ncase\ list\ will\ ''not''\ return\ its\ argument\ verbatim.\ \ On\ the\ `\[return\]`\ page\nI\ discuss\ a\ few\ other,\ safer\ approaches.\ \ The\ simplest\ one\ is\ to\ instead\ use\nsingle-argument\ `\[lindex\]`.\n\n\n\n**\ Some\ Tcl\ core\ commands\ require\ lists\ as\ argument\ or\ return\ lists\ **\n\n\ \ \ `\[after\]`:\ \ \ \n\n\ \ \ `\[apply\]`:\ \ \ \n\n\ \ \ `\[array\]`:\ \ \ \n\n\ \ \ `\[binary\]`:\ \ \ \n\n\ \ \ `\[chan\]`:\ \ \ \n\n\ \ \ `\[dde\]`:\ \ \ \n\n\ \ \ `\[dict\]`:\ \ \ \n\n\ \ \ `\[oo::define\]`:\ \ \ \n\n\ \ \ `\[oo::next\]`:\ \ \ \n\n\ \ \ `\[encoding\]`:\ \ \ \n\n\ \ \ `\[exec\]`:\ \ \ \n\n\ \ \ `\[fconfigure\]`:\ \ \ \n\n\ \ \ `\[file\]`:\ \ \ \n\n\ \ \ `\[glob\]`:\ \ \ \n\n\ \ \ `\[http\]`:\ \ \ \n\n\ \ \ `\[info\]`:\ \ \ \n\n\ \ \ `\[interp\]`:\ \ \ \n\n\ \ \ `\[library\]`:\ \ \ \n\n\ \ \ `\[msgcat\]`:\ \ \ \n\n\ \ \ `\[namespace\]`:\ \ \ \n\n\ \ \ `\[open\]`:\ \ \ \n\n\ \ \ `\[package\]`:\ \ \ \n\n\ \ \ `\[packagens\]`:\ \ \ \n\n\ \ \ `\[pid\]`:\ \ \ \n\n\ \ \ `\[pkgMkIndex\]`:\ \ \ \n\n\ \ \ `\[platform\]`:\ \ \ \n\n\ \ \ `\[proc\]`:\ \ \ \n\n\ \ \ `\[read\]`:\ \ \ \n\n\ \ \ `\[oo::refchan\]`:\ \ \ \n\n\ \ \ `\[regexp\]`:\ \ \ \n\n\ \ \ `\[registry\]`:\ \ \ \n\n\ \ \ `\[return\]`:\ \ \ \n\n\ \ \ `\[safe\]`:\ \ \ \n\n\ \ \ `\[scan\]`:\ \ \ \n\n\ \ \ `\[oo::self\]`:\ \ \ \n\n\ \ \ `\[socket\]`:\ \ \ \n\n\ \ \ `\[switch\]`:\ \ \ \n\n\ \ \ `\[tcltest\]`:\ \ \ \n\n\ \ \ `\[tm\]`:\ \ \ \n\n\ \ \ `\[trace\]`:\ \ \ \n\n\n\n**\ Page\ Authors\ **\n\n\ \ \ \[DKF\]:\ \ \ \n\n\ \ \ \[PYK\]:\ \ \ \n\n\n\n**\ References\ **\n\n\ \ \ 1:\ \ \ \[aspect\],\ \[Tcl\ Chatroom\],\ 2014-09-13\n\n} CALL {my revision list} CALL {::oo::Obj873636 process revision/list} CALL {::oo::Obj873634 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