Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/lassign?V=55
QUERY_STRINGV=55
CONTENT_TYPE
DOCUMENT_URI/revision/lassign
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.70.175.151
REMOTE_PORT45454
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR3.237.46.120
HTTP_CF_RAY86b993acdaa782ba-IAD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTclaudebot
HTTP_CF_CONNECTING_IP3.237.46.120
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 lassign As\ from\ 8.5,\ \[lassign\],\ the\ \[list\]\ assignment\ command,\ is\ in\ the\ \[Tcl\]\ \[core\]\ -\ see\ \[Changes\ in\ Tcl/Tk\ 8.5\]\ and\ \[TIP\]\ 57\ \[http://purl.org/tcl/tip/57.html\].\ Prior\ to\ that,\ it\ was\ in\ the\ \[TclX\]\ \[package\].\n`lassign`\ became\ a\ built-in\ command\ in\ Tcl\ \[Changes\ in\ Tcl/Tk\ 8.5%|%8.5\].\n\n**\ Documentation\ **\nIt\ takes\ a\ ''list''\ and\ assigns\ the\ values\ from\ it\ to\ each\ of\ the\ variables\ given\ by\ ''varName''\ in\ turn.\ Any\ values\ from\ the\ ''list''\ that\ are\ not\ assigned\ are\ returned\ as\ a\ sublist.\ Thus:\n===\nset\ end\ \[\['''lassign'''\ \{1\ 2\ 3\ 4\ 5\}\ a\ b\ c\]\]\n===\nwill\ set\ `\$a`\ to\ `1`,\ `\$b`\ to\ `2`,\ `\$c`\ to\ `3`,\ and\ `\$end`\ to\ “`4\ 5`”.\n<<br>>\nAny\ extra\ variables\ that\ don't\ match\ up\ to\ a\ list\ element\ are\ assigned\ the\ empty\ string.\n\nSee\ \[http://purl.org/tcl/home/man/tcl8.5/TclCmd/lassign.htm%|%the\ manual\ page%|%\]\ for\ full\ documentation.\n\n----\n\[TclX\]\ has\ supplied\ lassign\ since\ the\ early\ \[\[or\ mid-?\]\]\ '90s.\n\ \ \ \[http://www.tcl.tk/man/tcl/TclCmd/lassign.htm%|%official\ reference\]:\ \ \ \nExample\ usage:\n\ \ \ \ lassign\ \{value1\ value2\}\ variable1\ variable2\nin\ place\ of\n\ \ \ \ set\ variable1\ value1\n\ \ \ \ set\ variable2\ value2\n\ \ \ \[TIP\]\ \[http://purl.org/tcl/tip/57.html%|%57\]:\ \ \ proposed\ making\ the\ \[TclX\]\ `lassign`\ command\ a\ built-in\ Tcl\ command\ \n**\ Description\ **\n----\nActually,\ note\ that\ lassign\ takes\ a\ list\ and\ assigns\ each\ element\ to\ a\ variable.\ \ Thus,\ while\ the\ above\ is\ true,\ the\ list\ of\ values\ can\ have\ dozens\ of\ elements.\n\nFor\ example:\n\n\ \ \ lassign\ \[list\ 1\ 2\ 3\ 4\ 5\ 6\ 7\]\ variable1\ variable2\n\ \ \ puts\ \$variable1\n\ 1\n\ \ \ puts\ \$variable2\n\ 2\n`lassign`\ assigns\ values\ from\ a\ \[list\]\ to\ the\ specified\ variables,\ and\nThe\ more\ variables\ you\ supply,\ the\ more\ single\ values\ are\ assigned.\n======\n\[LV\]\ 2006\ Dec\ 06\ -\ here's\ another\ example\ of\ which\ one\ should\ be\ aware:\nwill\ set\ `\$a`\ to\ `1`,\ `\$b`\ to\ `2`,\ `\$c`\ to\ `3`,\ and\ `\$end`\ to\ `4\ 5`.\n\ %\ lassign\ \[list\ 1\ 2\]\ a\ b\ c\n\ %\ puts\ \$a\n\ 1\n\ %\ puts\ \$b\n\ 2\n\ %\ puts\ \$c\nIn\ \[lisp\]\ parlance:\n\ %\n======\nIn\ other\ words,\ note\ that\ if\ more\ variables\ are\ provided\ than\ values,\ the\nvariable\ is\ defined\ to\ be\ a\ 0\ length\ string,\ rather\ than\ either\ remaining\nundefined\ or\ retaining\ a\ previous\ value\ (if\ already\ defined).\nIf\ there\ are\ more\ ''varNames''\ than\ there\ are\ items\ in\ the\ list,\ the\ extra\n======none\n----\n''Does\ lassign\ in\ \[Tcl\]\ 8.5\ differ\ in\ any\ way\ from\ TclX's\ version?''\n%\nThey\ do\ not\ differ\ in\ any\ script-visible\ way.\ You\ call\ them\ with\ the\ same\ syntax.\ \ Same\ arguments\ to\ both\ implies\ same\ results\ from\ both.\nIn\ Tcl\ prior\ to\ 8.5,\ `\[foreach\]`\ was\ used\ to\ achieve\ the\ functionality\ of\nThe\ internal\ implementation\ is\ not\ the\ same\;\ the\ new\ \[\[lassign\]\]\ in\ Tcl\ 8.5\ makes\ use\ of\ the\ \[bytecode\]\ compiler.\n======\n\[DKF\]:\ The\ new\ implementation\ is\ also\ much\ more\ heavily\ tested.\ \ I've\ a\ bit\ of\ experience\ with\ being\ paranoiac\ about\ tests\ these\ days...\ :^/\n\n\[JMN\]:\ tclX\ doesn't\ seem\ to\ use\ a\ separate\ namespace\ for\ it's\ commands\ -\ so\ if\ we\ do\ a\ 'package\ require\ tclX'\ in\ Tcl\ 8.5+,\ which\ version\ of\ a\ command\ such\ as\ lassign\ will\ end\ up\ being\ used?\ \ \n----\n\[DKF\]\ cleverly\ points\ out\ that\ lassign\ makes\ a\ \[Perl\]lish\ \[\[shift\]\]\ this\ easy:\n\ \ \ \ \ \ proc\ shift\ \{\}\ \{\n\ \ \ \ \ \ \ \ \ \ global\ argv\n\ \ \ \ \ \ \ \ \ \ set\ argv\ \[lassign\ \$argv\ v\]\n\ \ \ \ \ \ \ \ \ \ return\ \$v\n\ \ \ \ \ \ \}\nOn\ the\ other\ hand,\ \[Hemang\ Lavana\]\ observes\ that\ TclXers\ already\nhave\ \"\[lvarpop\]\ ::argv\",\ an\ exact\ synonym\ for\ \"shift\".\n\n\n\ proc\ shift\ \{\}\ \{K\ \[lindex\ \$::argv\ 0\]\ \[set\ ::argv\ \[lrange\ \$::argv\ 1\ end\]\]\}\n======\n\n\ proc\ shift\ \{\}\ \{lindex\ \$::argv\ \[set\ ::argv\ \[lrange\ \$::argv\ 1\ end\]\;\ expr\ 0\]\}\n======\n\n\n\[KPV\]\ -\ For\ those\ who\ want\ to\ use\ \[\[lassign\]\]\ before\ Tcl\ 8.5,\nand\ without\ getting\ \[TclX\],\ here's\ a\ tcl-only\nversion\ of\ lassign:\n\n\ if\ \{\[info\ procs\ lassign\]\ ==\ \"\"\}\ \{\n\ \ \ \ \ \ \ \ set\ vlen\ \[llength\ \$values\]\n\ \ \ \ \ \ \ \ set\ alen\ \[llength\ \$args\]\n\n\ \ \ \ \ \ \ \ for\ \{set\ i\ \$vlen\}\ \{\$i\ <\ \$alen\}\ \{incr\ i\}\ \{\ \;#\ Make\ lists\ equal\ length\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ uplevel\ 1\ \[list\ foreach\ \$args\ \$values\ break\]\n\ \ \ \ \ \ \ \ return\ \[lrange\ \$values\ \$alen\ end\]\n\ \ \ \ \}\n\}\n\ \}\n\[jcw\]:\ Couldn't\ resist\ rewriting\ in\ a\ style\ I\ prefer.\ \ Chaq'un\ son\ gout\ -\ a\n\[jcw\]\ -\ Couldn't\ resist\ rewriting\ in\ a\ style\ I\ prefer.\ \ Chaq'un\ son\ gout\ -\ a\ matter\ of\ taste\ -\ of\ course:\n======\n\ if\ \{\[info\ procs\ lassign\]\ ==\ \"\"\}\ \{\n\ \ \ \ \ \ \ \ while\ \{\[llength\ \$values\]\ <\ \[llength\ \$args\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ values\ \{\}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ uplevel\ 1\ \[list\ foreach\ \$args\ \$values\ break\]\n\ \ \ \ \ \ \ \ lrange\ \$values\ \[llength\ \$args\]\ end\n\ \ \ \ \}\n\}\n\ \}\n\[KPV\]:\ But\ from\ an\ efficiency\ point\ of\ view,\ you're\ calling\ `\[llength\]`\ way\ too\n\[KPV\]\ -\ But\ from\ an\ efficiency\ point\ of\ view,\ you're\ calling\ '''llength'''\nway\ too\ many\ times--every\ iteration\ through\ the\ '''while'''\ loop\ does\ two\nunnecessary\ calls.\ How\ about\ this\ version--your\ style\ but\ more\ efficient:\n======\n\ if\ \{\[info\ procs\ lassign\]\ ==\ \"\"\}\ \{\n\ \ \ \ \ \ \ \ set\ alen\ \[llength\ \$args\]\n\ \ \ \ \ \ \ \ set\ vlen\ \[llength\ \$values\]\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ while\ \{\[incr\ vlen\]\ <=\ \$alen\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ values\ \{\}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ uplevel\ 1\ \[list\ foreach\ \$args\ \$values\ break\]\n\ \ \ \ \ \ \ \ lrange\ \$values\ \$alen\ end\n\ \ \ \ \}\n\}\n\ \}\n\[jcw\]\ interjects:\ Keith...\ are\ you\ sure\ `\[llength\]`\ is\ slower?\ (be\ sure\ to\ test\n''Keith...\ are\ you\ sure\ \[llength\]\ is\ slower?\ (be\ sure\ to\ test\ inside\ a\ \[proc\]\ body)\ -\[jcw\]''\nIt\ must\ be\ my\ assembler/C\ background\ but\ I\ see\ those\ function\ calls,\ especially\nthe\ one\ returning\ a\ constant\ value\ and\ wince.\ \nBut\ you're\ correct,\ calling\ llength\ is\ no\ slower\ than\ accessing\ a\ variable.\ It\ \nguess\ the\ byte\ compiler\ is\ optimizing\ out\ the\ actual\ call.\ \[KPV\]\n\[kpv\]\ continues:\ It\ must\ be\ my\ assembler/C\ background\ but\ I\ see\ those\ function\n\[DKF\]:\ ''\[llength\]''\ is\ indeed\ bytecoded.\n\[DKF\]:\ `\[llength\]`\ is\ indeed\ bytecoded.\n\[sbron\]\ -\ I\ see\ no\ reason\ to\ massage\ the\ values\ list\ at\ all.\ The\ \[foreach\]\ will\ do\ exactly\ the\ same\ thing\ even\ if\ the\ values\ list\ is\ shorter\ than\ the\ \[args\]\ list.\ I.e.\ this\ should\ be\ all\ that's\ needed:\n\[sbron\]:\ I\ see\ no\ reason\ to\ massage\ the\ values\ list\ at\ all.\ `\[foreach\]`\ will\ do\n\ if\ \{\[info\ procs\ lassign\]\ eq\ \"\"\}\ \{\n\ \ \ \ proc\ lassign\ \{values\ args\}\ \{\n\ \ \ \ \ \ \ \ uplevel\ 1\ \[list\ foreach\ \$args\ \$values\ break\]\n\ \ \ \ \ \ \ \ lrange\ \$values\ \[llength\ \$args\]\ end\n\ \ \ \ \}\n\ \}\n\nThis\ version\ does\ not\ work\ as\ described\ in\ the\ documentation\ for\ lassign\ for\nThis\ version\ does\ not\ work\ as\ described\ in\ the\ documentation\ for\ lassign\ for\ this\ case:\n======\n\ %\ lassign\ \[list\]\ a\ b\ c\n\ %\ set\ a\n\ can't\ read\ \"a\":\ no\ such\ variable\n\[sbron\]:\ You\ are\ right,\ I\ just\ noticed\ that\ myself\ too.\ Improved\ version:\n\[sbron\]\ -\ You\ are\ right,\ I\ just\ noticed\ that\ myself\ too.\ Improved\ version:\n======\n\ if\ \{\[info\ procs\ lassign\]\ eq\ \"\"\}\ \{\n\ \ \ \ proc\ lassign\ \{values\ args\}\ \{\n\ \ \ \ \ \ \ \ uplevel\ 1\ \[list\ foreach\ \$args\ \[linsert\ \$values\ end\ \{\}\]\ break\]\n\ \ \ \ \ \ \ \ lrange\ \$values\ \[llength\ \$args\]\ end\n\ \ \ \ \}\n\ \}\n\[AMG\]:\ I\ prefer\ to\ use\ `\[catch\]`\ to\ check\ for\ a\ command's\ existence.\ \ Not\ only\n\[sdw\]\ Shouldn't\ that\ be\ `\[\[\[info\ commands\]\ lassign\]\]`?\n======\n\[DKF\]:\ Absolutely.\ Neither\ the\ native\ Tcl\ version\ nor\ the\ TclX\ version\ are\ procedures,\ and\ both\ are\ faster\ than\ the\ scripted\ versions\ above.\n\n\[AMG\]:\ I\ prefer\ using\ \[catch\]\ to\ detect\ the\ existence\ of\ a\ command,\ since\ it\ also\ allows\ me\ to\ detect\ if\ a\ command\ supports\ an\ option\ or\ \[ensemble\]-like\ subcommand.\n\n\[Duoas\]:\ The\ \[expr\]\ 'eq'\ doesn't\ work\ with\ anything\ before\ Tcl\ 8.4.\ Also,\ you\ really\ should\ check\ against\ an\ empty\ \$args\ list.\n\n\ if\ \{\"\[info\ commands\ ::lassign\]\[info\ procs\ ::lassign\]\"\ ==\ \"\"\}\ \{\n\ \ \ \ proc\ ::lassign\ \{list\ args\}\ \{\n\ \ \ \ \ \ \ \ if\ \{\$args\ ==\ \"\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ return\ -code\ error\ \{wrong\ #\ args:\ should\ be\ \"lassign\ list\ varName\ ?varName\ ...?\"\}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ uplevel\ 1\ \[list\ foreach\ \$args\ \[linsert\ \$list\ end\ \{\}\]\ break\]\n\ \ \ \ \ \ \ \ return\ \[lrange\ \$list\ \[llength\ \$args\]\ end\]\n\ \ \ \ \}\n\ \}\n\n\ \ \ *\ The\ 'commands'\ and\ 'procs'\ tests\ against\ any\ existing\ command\ ''or''\ proc\ named\ \"lassign\".\n\ \ \ *\ The\ '=='\ is\ valid\ Tcl\ syntax\ for\ versions\ prior\ to\ 8.4.\n\ \ \ *\ The\ error\ result\ is\ identical\ to\ (8.5.5's)\ error\ result\ for\ an\ empty\ list\ of\ variable\ names.\n\ \ \ *\ I\ like\ an\ explicit\ 'return'\ --\ though\ it\ could,\ as\ above,\ be\ omitted\ if\ you\ feel\ performance\ is\ an\ issue\ on\ old\ Tcls.\nMy\ \$0.02.\n\n\[DKF\]:\ All\ procedures\ ''are''\ commands.\ Hence\ if\ \[info\ procs\]\ finds\ them,\ so\ will\ \[info\ commands\]\ (apart\ from\ a\ few\ horrid\ nuances\ that\ don't\ matter\ here).\ The\ best\ approach\ (used\ in\ the\ Tcl\ test\ suite)\ is\ to\ check\ the\ length\ of\ list\ returned\ by\ \[info\ commands\]\;\ if\ the\ command\ name\ has\ no\ glob\ metacharacters\ in\ (as\ with\ “lassign”)\ then\ that's\ going\ to\ be\ 0\ or\ 1…\n\n----\n\[CMcC\]:\ I\ may\ be\ just\ exceptionally\ grumpy\ this\ morning\ 2005/11/14\ but\ the\ behavior\ of\ supplying\ default\ empty\ values\ to\ extra\ variables\ means\ you\ can't\ distinguish\ between\ a\ trailing\ var\ with\ no\ matching\ value,\ and\ one\ with\ a\ value\ of\ \{\}.\ \ Needs\ an\ option,\ -greedy\ or\ something,\ to\ distinguish\ between\ the\ two\ cases.\ \ Oh,\ ''and''\ it\ annoys\ me\ that\ \[\[lset\]\]\ is\ already\ taken,\ because\ \[\[lassign\]\]\ doesn't\ resonate\ well\ with\ \[\[set\]\].\n\n----\n\[KS\]:\ I\ agree\ with\ CMcC\ on\ both\ counts\ -\ supplying\ a\ default\ empty\ value\ when\ no\ matching\ value\ is\ provided\ is\ bad\ form\;\ and\ \[lset\]/\[set\]\ would\ have\ been\ better\ than\ lassign/set.\ \ However,\ I\ have\ a\ few\ other\ tweaks\ I\ would\ suggest,\ then\ I'll\ tie\ it\ all\ together\ with\ code\ to\ do\ what\ I\ suggest.\ \ \n\nFirst,\ there\ is\ a\ fundamental\ assymetry\ between\ the\ set\ and\ lassign\ behaviors\ -\ set\ copies\ right\ to\ left\;\ lassign\ goes\ from\ left\ to\ right.\ \ In\ fact,\ most\ computer\ languages\ use\ the\ idiom\ of\ right\ to\ left\ for\ assignment.\ \ However,\ there\ are\ certain\ advantages\ to\ the\ left\ to\ right\ behavior\ of\ lassign\ (it\ Tcl).\ \ For\ example,\ when\ assigning\ a\ list\ of\ variables\ to\ the\ contents\ of\ args.\ \ Using\ the\ right\ to\ left\ idiom\ would\ require\ an\ \[eval\].\ \ \n\nStill,\ the\ right\ to\ left\ behavior\ also\ has\ its\ benefits.\ \ It\ allows\ you\ to\ perform\ computations\ on\ the\ values\ before\ performing\ the\ assignment.\ \ Take,\ for\ example,\ this\ definition\ of\ factorial\ (borrowed\ from\ \[Tail\ call\ optimization\]):\n\n\ \ \ \ proc\ fact0\ \{\ n\ \}\ \{\n\ \ \ \ \ \ \ \ set\ result\ 1.\n\ \ \ \ \ \ \ \ while\ \{\ \$n\ >\ 1\ \}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ result\ \[expr\ \{\ \$result\ *\ \$n\ \}\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ n\ \[expr\ \{\ \$n\ -\ 1\ \}\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ return\ \$result\n\ \ \ \ \}\n\[JMN\]:\ tclX\ doesn't\ seem\ to\ use\ a\ separate\ namespace\ for\ its\ commands\ so\ if\ we\nNow,\ with\ lassign\ (as\ is),\ we\ can\ \"improve\"\ this\ as\ follows:\n\n\ \ \ \ proc\ fact0\ \{\ n\ \}\ \{\n\ \ \ \ \ \ \ \ set\ result\ 1.\n\ \ \ \ \ \ \ \ while\ \{\ \$n\ >\ 1\ \}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ lassign\ \[list\ \[expr\ \{\ \$result\ *\ \$n\ \}\]\ \[expr\ \{\ \$n\ -\ 1\ \}\]\]\ result\ n\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ return\ \$result\n\ \ \ \ \}\n===\nI'm\ hard\ pressed\ to\ believe\ that\ this\ is\ better.\ \ However,\ if\ we\ changed\ lassign\ to\ be\ \"lassign\ vars\ args\",\ we\ can\ write\ this\ as:\n\n\ \ \ \ proc\ fact0\ \{\ n\ \}\ \{\n\ \ \ \ \ \ \ \ set\ result\ 1.\n\ \ \ \ \ \ \ \ while\ \{\ \$n\ >\ 1\ \}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ lassign\ \{result\ n\}\ \[expr\ \{\ \$result\ *\ \$n\ \}\]\ \[expr\ \{\ \$n\ -\ 1\ \}\ \]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ return\ \$result\n\ \ \ \ \}\n\nTo\ my\ eye,\ at\ least,\ this\ is\ much\ more\ readable.\ \ \n\nSo,\ I\ suggest\ that\ we\ use\ two\ functions:\ lassign\ and\ lassignr\ (the\ \"r\"\ is\ for\ \"reverse\").\ \ lassign\ would\ be\ used\ for\ the\ \"standard\"\ behavior:\ right\ to\ left.\ \ lassignr\ would\ then\ be\ used\ for\ left\ to\ right.\ \ This\ is\ backwards\ from\ the\ way\ it\ is\ defined\ above\ for\ TclX\ and\ Tcl\ 8.5.\ \ Nonetheless,\ this\ behavior\ aligns\ better\ with\ our\ training\ and\ intuition.\ \ \n\nAlso,\ this\ provides\ a\ couple\ of\ other\ benefits.\ \ First,\ the\ parallel\ to\ set\ is\ much\ more\ obvious.\ \ lassign\ and\ set\ both\ copy\ from\ right\ to\ left\ (of\ course,\ we\ are\ still\ left\ with\ the\ assymetry\ in\ their\ names\ -\ I'll\ get\ to\ that\ later).\ \ And,\ we\ can\ now\ see\ why\ assigning\ an\ empty\ string\ to\ a\ variable\ which\ doesn't\ have\ a\ value\ supplied\ is\ bad\ form\;\ this\ is\ not\ what\ set\ does!\ \ If\ you\ enter\ \"set\ a\"\ you\ get\ the\ value\ of\ \"a\",\ you\ don't\ assign\ the\ empty\ string\ to\ \"a\".\ \ lassign\ should\ not\ either.\ \ If\ you\ want\ to\ assign\ the\ empty\ string\ using\ set\ you\ would\ enter:\n\n\ \ \ \ set\ a\ \{\}\n\nWith\ lassign,\ you\ would\ do\ something\ similar:\n\n\ \ \ \ lassign\ \{a\ b\ c\}\ 1\ \{\}\n\nHere,\ \"a\"\ gets\ \"1\",\ \"b\"\ gets\ the\ empty\ string,\ and\ c\ is\ not\ touched.\ \ This\ behavior\ parallels\ that\ of\ set\ nicely.\ \ Except\ that\ set\ returns\ the\ value\ set\;\ lassign\ does\ not.\ \ lassign\ returns\ \"unused\"\ values.\ \ So,\ let's\ take\ another\ step\ in\ that\ direction\;\ we'll\ have\ lassign\ and\ lassignr\ return\ the\ \"used\"\ values\ instead.\ \ \n\nBut,\ this\ destroys\ a\ nice\ property\ of\ lassign.\ \ Can\ we\ recover\ that\ property?\ \ Almost.\ \ We\ can\ do\ what\ \"proc\"\ does\;\ we\ can\ use\ the\ \"args\"\ variable\ name\ to\ indicate\ a\ variable\ that\ sucks\ up\ all\ the\ remaining\ items.\ \ So,\ now\ we\ get:\n\n\ \ \ \ lassign\ \{a\ b\ args\}\ 1\ 2\ 3\ 4\ 5\ 6\n\n\"a\"\ gets\ \"1\",\ \"b\"\ gets\ \"2\",\ and\ args\ gets\ \{3\ 4\ 5\ 6\}.\ \ Of\ course,\ we\ would\ make\ lassignr\ work\ similarly:\n\n\ \ \ \ lassignr\ \{1\ 2\ 3\ 4\ 5\ 6\}\ a\ b\ args\n\nBut,\ now\ that\ we\ have\ one\ of\ the\ nice\ behaviors\ of\ the\ proc\ \"assignment\",\ what\ about\ that\ other\ useful\ feature:\ default\ values?\ \ We\ can\ do\ that\ as\ well.\ \ So,\ if\ a\ value\ is\ not\ provided,\ then\ the\ default\ value\ is\ used:\n\n\ \ \ \ lassign\ \{a\ \{b\ 2\}\}\ one\n\n\"b\"\ gets\ the\ value\ \"2\".\ \ This\ also\ provides\ for\ the\ assignment\ of\ an\ empty\ list\ to\ a\ variable\ if\ the\ value\ is\ not\ provided.\ \ So,\ those\ who\ liked\ that\ behavior\ can\ have\ their\ wish\ as\ well:\n\n\ \ \ \ lassign\ \{a\ \{b\ \{\}\}\}\ one\n\nBut,\ simple\ defaults\ are\ not\ always\ adequate.\ \ This\ only\ provides\ for\ constants\;\ if\ something\ beyond\ that\ is\ required,\ then\ explicit\ lists\ are\ needed.\ \ For\ example:\n\n\ \ \ \ lassign\ \[list\ a\ \[list\ b\ \$defaultb\]\]\ one\n\nThis\ gets\ to\ be\ ugly.\ \ So,\ we\ make\ one\ more\ provision:\ we\ allow\ variable\ references\ within\ the\ defaults:\ \ \n\n\ \ \ \ lassign\ \{a\ \{b\ \$defaultb\}\}\ one\n\nNow,\ this\ really\ begins\ to\ provide\ the\ simplicity\ and\ power\ that\ we\ should\ expect\ from\ a\ general\ purpose\ utility\ routine.\ \ And,\ it\ parallels\ other\ behaviors\ within\ Tcl\ (proc\ and\ set)\ well\ so\ that\ it\ feels\ natural.\ \ \n\nBut,\ we're\ still\ left\ with\ this\ lassign/set\ dichotomy.\ \ We\ can't\ easily\ rename\ \"lassign\"\ to\ be\ \"lset\"\ (without\ potentially\ breaking\ someone's\ code).\ \ But,\ notice\ that\ lassign\ now\ provides\ features\ that\ set\ does\ not.\ \ So,\ instead,\ let's\ create\ an\ assign\ procedure\ that\ provides\ these\ same\ features,\ but\ only\ for\ a\ single\ value:\n\n\ \ \ \ assign\ \{x\ 3\}\ 7\n\nSets\ x\ to\ 7.\ \ If\ no\ value\ is\ provided,\ x\ will\ be\ 3.\ \ \n\nSo,\ we\ now\ have\ three\ functions\ (assign/lassign/lassignr)\ that\ collectively\ provide\ useful\ and\ powerful\ features\ that,\ used\ wisely,\ can\ make\ your\ code\ more\ readable\ and\ maintainable.\ \ You\ could\ argue\ that\ you\ only\ \"need\"\ one\ of\ these\ (pick\ one)\ -\ the\ others\ are\ easily\ constructed\ from\ whichever\ is\ chosen.\ \ However,\ having\ all\ three\ provides\ symmetry\ and\ flexibility.\ \ \n\nI\ have\ provided\ the\ definitions\ of\ these\ functions\ below.\ \ The\ implementation\ is\ less\ interesting\ than\ the\ simple\ power\ these\ routines\ provide.\ \ I'm\ certain\ that\ many\ of\ you\ can\ improve\ these\ implementations.\ \ And,\ if\ you\ don't\ like\ my\ rationale\ on\ the\ naming\ of\ lassignr\;\ then\ you\ can\ swap\ the\ names.\ \ It's\ easy\ to\ change\ other\ aspects\ as\ well\;\ for\ example,\ if\ you\ still\ want\ lassign\ to\ return\ the\ unused\ values,\ it's\ relatively\ easy\ to\ modify\ these\ routines.\ \ \n\n\ \ \ \ proc\ assign\ \{var\ args\}\ \{\n\ \ \ \ \ \ \ \ if\ \{\ \[llength\ \$var\]\ >\ 1\ \}\ \{\ uplevel\ set\ \$var\ \}\n\ \ \ \ \ \ \ \ uplevel\ set\ \[lindex\ \$var\ 0\]\ \$args\n\ \ \ \ \}\n\ \ \ \ \n\ \ \ \ proc\ lassign\ \{vars\ args\}\ \{\n\ \ \ \ \ \ \ \ if\ \{\ (\[lindex\ \$vars\ end\]\ eq\ \"args\")\ &&\ (\[llength\ \$args\]\ >\ \[llength\ \$vars\])\ \}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ last\ \[expr\ \[llength\ \$vars\]\ -\ 1\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ args\ \[lreplace\ \$args\ \$last\ end\ \[lrange\ \$args\ \$last\ end\]\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ ##\ \ This\ is\ required\ so\ that\ we\ can\ distinguish\ between\ the\ value\ \{\}\ and\ no\ value\n\ \ \ \ \ \ \ \ foreach\ val\ \$args\ \{\ lappend\ vals\ \[list\ \$val\]\ \}\n\ \ \ \ \ \ \ \ foreach\ var\ \$vars\ val\ \$vals\ \{\ lappend\ res\ \[uplevel\ assign\ \[list\ \$var\]\ \$val\]\ \}\n\ \ \ \ \ \ \ \ return\ \$res\n\ \ \ \ \}\n\n\ \ \ \ proc\ lassignr\ \{vals\ args\}\ \{\n\ \ \ \ \ \ \ \ uplevel\ lassign\ \[list\ \$args\]\ \$vals\n\ \ \ \ \}\n\n\[FM\]\ here's\ a\ quick\ way\ to\ assign\ with\ default\ value\ (using\ apply)\n======\n\ \ \ \ proc\ args\ \{spec\ list\}\ \{\n\ \ \ \ \ \ \ \ apply\ \[list\ \$spec\ \[list\ foreach\ e\ \$spec\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ uplevel\ 2\ \[list\ set\ \[lindex\ \$e\ 0\]\ \[set\ \[lindex\ \$e\ 0\]\]\]\n\ \ \ \ \ \ \ \ \}\]\]\ \{*\}\$list\n\ \ \ \ \}\n\ \ \ \ set\ L\ \[list\]\n\ \ \ \ args\ \{\{a\ 0\}\ \{b\ 0\}\ \{c\ 0\}\ args\}\ \$L\n======\n\[slebetman\]\ KS,\ your\ proposal\ seems\ to\ illustrate\ that\ you\ don't\ ''get''\ the\ idea\ of\ '''lassign'''.\ For\ several\ years\ now\ I\ have\ used\ my\ own\ homegrown\ proc\ '''unlist'''\ that\ has\ the\ exact\ same\ syntax\ and\ semantics\ of\ '''lassign'''.\ The\ semantics\ behind\ '''lassign'''\ is\ not\ like\ \[set\]\ at\ all\ but\ more\ like\ \[scan\]\ where\ the\ semantics\ in\ most\ programming\ languages\ (at\ least\ in\ C\ and\ Python)\ is\ indeed\ assignment\ from\ left\ to\ right.\ The\ general\ use\ of\ a\ ''scanning''\ function\ like\ '''lassign'''\ is\ that\ given\ an\ opaque\ list\ (one\ that\ you\ did\ not\ create)\ split\ it\ into\ individual\ variables.\n\nIf\ you\ really\ understand\ the\ semantics\ '''lassign'''\ was\ trying\ to\ achieve\ then\ you\ wouldn't\ have\ proposed\ your:\n\n\ \ \ lassign\ vars\ args\n\nTo\ achieve\ the\ semantics\ of\ '''lassign'''\ but\ with\ right\ to\ left\ assignment\ you\ should\ have\ proposed:\n\n\ \ \ lassign\ vars\ list\n\nOf\ course,\ your\ proposal\ above\ can\ work\ with\ Tcl8.5\ using\ \[\{*\}\]:\n\n\ \ \ lassign\ \{var1\ var2\ var3\}\ \{*\}\$list\n\nBut\ that\ means\ for\ 90%\ of\ cases\ where\ you\ would\ use\ '''lassign'''\ you\ will\ have\ to\ also\ use\ \{*\}.\ Actually\ Tcl8.4\ already\ has\ a\ command\ which\ does\ what\ lassign\ is\ supposed\ to\ do\ but\ with\ a\ syntax\ that\ assigns\ from\ right\ to\ left:\ \[foreach\].\ Indeed,\ my\ home-grown\ '''unlist'''\ proc\ is\ simply\ a\ wrapper\ around\ foreach\ as\ demonstrated\ by\ \[sbron\]\ above.\ With\ 8.4,\ if\ you\ want\ lassign-like\ functionality\ you\ would\ do:\n\n\ \ \ foreach\ \{var1\ var2\ var3\}\ \$list\ \{\}\n\n\n\[KS\]:\ \[slebetman\],\ you're\ right,\ I\ did\ not\ ''get''\ that\ the\ semantics\ of\ '''lassign'''\ (which\ is\ mnemonic\ for\ \"list\ assign\"\ should\ match\ those\ of\ \[scan\]\ and\ not\ \[set\]\ (which\ is\ a\ synonym\ for\ \"assign\").\ \ Most\ languages\ refer\ to\ the\ operation\ of\ putting\ a\ value\ into\ a\ variable\ as\ \"assignment\",\ and,\ with\ only\ specialized\ exception,\ this\ is\ done\ right-to-left.\ \ I'm\ certain\ that\ others\ have\ made\ this\ same\ mistake\;\ in\ fact,\ I\ count\ myself\ in\ good\ company,\ since\ the\ authors\ of\ the\ lassign\ TIP\ #57\ \[http://purl.org/tcl/tip/57.html\]\ for\ Tcl\ 8.5\ make\ the\ same\ assumption:\n\n\ \ \ \ It\ would\ be\ more\ logical\ if\ the\ developer\ could\ write\ the\ following:\n\n\ \ \ \ \ \ \ \ set\ \{x\ y\}\ \[LocateFeature\ \$featureID\]\n\n\ \ \ \ or\n\n\ \ \ \ \ \ \ \ mset\ \{x\ y\}\ \[LocateFeature\ \$featureID\]\n\nSo,\ you\ see,\ when\ TIP\ #57\ was\ written,\ the\ thinking\ was\ in\ terms\ of\ right-to-left\ semantics\ (and,\ as\ a\ synonym\ to\ \[set\]).\ \ The\ fact\ that\ they\ decided\ to\ go\ with\ the\ left-to-right\ semantics\ was\ likely\ due\ to\ the\ issue\ that\ you\ point\ out\ about\ requiring\ an\ \[eval\]\ or\ \{*\},\ not\ that\ they\ were\ thinking\ in\ terms\ of\ \[scan\].\n\nBut,\ your\ point\ does\ suggest\ that\ a\ better\ name\ for\ '''lassign'''\ with\ left-to-right\ semantics\ is\ '''lscan'''.\ \ However,\ I\ was\ not\ ignorant\ of\ the\ concern\ with\ requiring\ an\ \[eval\]\ or\ \{*\}.\ \ I\ was\ not\ proposing\ ''eliminating''\ the\ left-to-right\ semanitcs,\ but\ adding\ the\ right-to-left\ semantics.\ \ What\ was\ left\ was\ more\ a\ discussion\ of\ proper\ naming.\ \ I\ think\ that\ you\ have\ helped\ to\ show\ that\ '''lassign'''\ should\ be\ used\ for\ right-to-left\ semantics,\ and\ '''lscan'''\ for\ left-to-right.\ \ \n\nYou\ also\ did\ not\ ''get''\ that\ I\ had\ much\ more\ to\ say\ than\ simply\ whether\ '''lassign'''\ should\ be\ left-to-right\ or\ right-to-left.\ \ For\ example,\ I\ made\ a\ proposal\ to\ allow\ for\ default\ values\ to\ be\ supplied\ when\ no\ value\ is\ available\ in\ the\ scan/assignment,\ in\ the\ manner\ of\ \[proc\].\ \ \n\nThis\ is\ not\ a\ trivial\ concern.\ \ Take,\ for\ example,\ the\ behaviors\ of\ \[scan\]\ and\ \[regexp\].\ \ \[regexp\]\ assigns\ \{\}\ to\ a\ variable\ argument\ if\ there\ is\ no\ matching\ value\ in\ the\ string\ (but,\ only\ if\ the\ match\ succeeded).\ \ However,\ \[scan\]\ only\ assigns\ values\ to\ those\ variables\ for\ which\ it\ finds\ a\ match\;\ an\ unmatched\ variable\ is\ not\ touched.\ \ \n\nThis\ leads\ to\ two\ different\ idioms\ for\ providing\ default\ values.\ \ The\ following\ example,\ based\ on\ an\ example\ in\ \[http://www.tcl.tk/man/tcl8.4/TclCmd/scan.htm\],\ uses\ \[scan\]\ and\ \[regexp\]\ to\ parse\ a\ simple\ color\ specification\ of\ the\ form\ #RRGGBB,\ where\ RR,\ GG,\ and\ BB\ are\ 2-digit\ hex\ numbers.\ \ If\ a\ value\ is\ missing\ (eg,\ #5004),\ then\ it\ defaults\ to\ 80.\ \ \n\n\ \ \ \ ##\ \ Using\ \[scan\]\n\ \ \ \ set\ r\ 80\n\ \ \ \ set\ g\ 80\n\ \ \ \ set\ b\ 80\n\ \ \ \ scan\ \$rgb\ \"#%2x%2x%2x\"\ r\ g\ b\n\ \ \ \ set\ resultRgb\ \[list\ \$r\ \$g\ \$b\]\n\ \ \ \ \n\ \ \ \ ##\ \ Using\ \[regexp\]\n\ \ \ \ regexp\ \{\$#(..)?(..)?(..)?^\}\ \$rgb\ r\ g\ b\n\ \ \ \ if\ \{\ !\ \[llength\ \$r\]\ \}\ \{\ set\ r\ 80\ \}\n\ \ \ \ if\ \{\ !\ \[llength\ \$g\]\ \}\ \{\ set\ g\ 80\ \}\n\ \ \ \ if\ \{\ !\ \[llength\ \$b\]\ \}\ \{\ set\ b\ 80\ \}\n\ \ \ \ set\ resultRgb\ \[list\ \$r\ \$g\ \$b\]\n\nAs\ you\ can\ see,\ the\ idioms\ required\ are\ different\ in\ each\ case.\ \ If,\ as\ you're\ developing\ code,\ you\ start\ with\ the\ \[scan\]\ approach,\ then\ decide\ you\ need\ to\ support\ something\ more\ sophisticated\ (eg,\ you\ want\ to\ have\ decimal,\ octal,\ or\ hex\ numbers),\ then\ you\ need\ to\ remember\ to\ change\ not\ just\ the\ parsing,\ but\ the\ method\ of\ assigning\ defaults\ as\ well.\ \ \n\nNote\ that\ this\ also\ demonstrates\ again\ that\ providing\ a\ default\ value\ (eg,\ \{\})\ when\ no\ value\ is\ provided\ really\ ought\ to\ be\ defined\ by\ the\ application\ and\ not\ the\ operation.\ \ The\ method\ of\ using\ defaults\ with\ \[scan\]\ is\ more\ straightforward\ (and\ amenable\ to\ using\ \[lassign\]\ or\ \[lscan\])\ than\ the\ method\ with\ \[regexp\].\ \ \n\nThe\ solution\ that\ I\ proposed\ was\ to\ make\ applying\ defaults\ similar\ to\ the\ way\ that\ defaults\ are\ handled\ with\ \[proc\]:\ \{var\ dflt\}.\ \ In\ fact,\ I\ would\ go\ a\ step\ farther\ and\ suggest\ that\ this\ idiom\ should\ be\ available\ to\ all\ Tcl\ operations\ that\ assign\ values\ to\ variables\ (including\ \[scan\]\ and\ \[regexp\]).\ \ But,\ I\ think\ that\ this\ is\ unlikely\ to\ occur,\ and\ is\ beyond\ the\ scope\ of\ what\ I\ was\ discussing.\ \ \n\nThe\ real\ point\ of\ my\ original\ posting\ was\ to\ demonstrate\ the\ utility,\ flexibility,\ power,\ and\ readability\ or\ using\ this\ idiom.\ \ I\ think\ it's\ a\ shame\ to\ limit\ that\ idiom\ to\ \[proc\].\ \ The\ most\ general\ application\ of\ it\ is\ to\ use\ it\ for\ assignment,\ which\ is\ what\ I\ showed.\ \ \n\n\[slebetman\]:\ I\ agree\ with\ the\ defaults\ mechanism.\ Especially\ since\ we're\ so\ used\ to\ using\ it\ in\ \[proc\].\ I\ wish\ we\ have\ it\ in\ all\ commands\ that\ assigns\ values\ to\ multiple\ variables:\n\n\ \ lassign\ \$foo\ \{a\ 0\}\ \{b\ \{\}\}\ \{c\ \"none\"\}\n\ \ scan\ \$rgb\ \"#%2x%2x%2x\"\ \{r\ 80\}\ \{g\ 80\}\ \{b\ 80\}\n\ \ regexp\ \{\$#(..)?(..)?(..)?^\}\ \$rgb\ \{r\ 80\}\ \{g\ 80\}\ \{b\ 80\}\n\ \ foreach\ \{x\ \{y\ 0\}\ \{z\ 100\}\}\ \$argv\ \{..\}\n\nI\ think\ such\ commands\ should\ check\ if\ the\ variable\ it\ is\ assigning\ to\ is\ a\ pair\ of\ words\ of\ which\ the\ second\ word\ is\ the\ default\ value.\ Assigning\ an\ empty\ string\ have\ always\ seemed\ to\ me\ too\ much\ like\ the\ hackish\ NULL\ value\ trick\ in\ C\ (the\ number\ of\ times\ I\ had\ to\ restructure\ apps\ because\ the\ customer\ insisted\ that\ zero\ is\ a\ valid\ value\ and\ should\ not\ signify\ undefined...).\n\nThe\ only\ downside\ I\ can\ think\ of\ is\ that\ this\ breaks\ apps\ with\ spaces\ in\ variable\ names.\ But\ then\ again,\ most\ of\ us\ are\ used\ to\ not\ writing\ spaces\ in\ variable\ names\ and\ we\ are\ used\ to\ this\ syntax\ in\ \[proc\].\n\nBTW,\ I\ also\ think\ \[lassign\]\ is\ a\ bad\ name\ for\ this\ operation.\ It\ makes\ much\ more\ sense\ if\ we\ instead\ use\ the\ name\ \[lassign\]\ to\ mean\ '''assign\ \"things\"\ to\ a\ list'''\ which\ fits\ your\ syntax\ proposal.\ My\ personal\ preference\ is\ still\ '''unlist'''\ (when\ we\ finally\ get\ 8.5\ I'll\ be\ doing\ an\ interp\ alias\ \{\}\ unlist\ \{\}\ lassign).\ '''lscan'''\ doesn't\ sound\ right\ to\ me\ but\ '''lsplit'''\ sounds\ just\ right\ for\ '''splitting\ a\ list\ into\ individual\ variables'''.\n\n\[DKF\]:\ The\ name\ comes\ from\ \[TclX\].\ Choosing\ a\ different\ name\ or\ argument\ syntax\ to\ that\ very\ well\ known\ piece\ of\ code\ is\ not\ worth\ it\;\ just\ gratuitous\ incompatability.\n\n----\n\[fredderic\]:\ I\ really\ don't\ see\ what\ all\ the\ fuss\ is\ about.\ \ \[lassign\]\ is\ fine\ just\ the\ way\ it\ is,\ \[lset\]\ is\ already\ taken,\ anything-'''scan'''\ sounds\ like\ it\ does\ a\ heck\ of\ a\ lot\ more\ than\ just\ assigning\ words\ to\ variables,\ and\ the\ concept\ of\ \[proc\]-like\ default\ values\ just\ makes\ me\ shudder...\ \ Even\ in\ the\ definition\ of\ a\ \[proc\]!\ \ \;)\n\nSomething\ I\ ''would''\ like\ to\ see,\ is\ an\ '''lrassign'''\ that\ does\ the\ ''left-to-right''\ thing,\ and\ ''maybe''\ some\ variant\ or\ option\ to\ \[lassign\]\ that\ takes\ a\ second\ list\ of\ ''default''\ values:\n\n\ lassign-with-defs\ defaultsList\ valuesList\ ?variable\ ...?\n\nwhere\ the\ defaults\ list\ would\ be\ empty-string-extended\ to\ the\ number\ of\ variables\ given\ (any\ extra\ defaults\ would\ simply\ be\ ignored),\ the\ values\ list\ wouldn't\ (any\ extra\ values\ would\ be\ returned\ as\ per\ usual),\ so\ you'd\ end\ up\ with:\n\n\ lassign-with-defs\ \{1\ 2\ 3\}\ \{a\ \{\}\}\ w\ x\ y\ z\n\nbeing\ the\ equivalent\ of:\n\n\ set\ w\ a\ \ \ \ \;#\ from\ values\ list\n\ set\ x\ \{\}\ \ \ \;#\ also\ from\ values\ list\n\ set\ y\ 3\ \ \ \ \;#\ 3rd\ default\ value\ carried\ through\n\ set\ z\ \{\}\ \ \ \;#\ empty-string\ expanded\ defaults\n\ #\ with\ both\ arguments\ consumed,\ and\ empty\ string\ is\ returned\n\nThe\ old\ filling-with-empty-strings\ \[lassign\]\ behaviour\ would\ thus\ be\ achieved\ by\ simply\ giving\ it\ an\ empty\ default\ values\ list,\ and\ the\ whole\ thing\ would\ be\ absolutely\ fabulous.\ \ \;)\n\nOf\ course\ the\ catch,\ is\ that\ if\ you\ simply\ take\ away\ the\ filling-with-empty-strings\ behaviour\ from\ \[lassign\],\ then\ the\ defaults\ capability\ is\ created\ by\ simply\ doing\ two\ \[lassign\]s.\ \ A\ little\ wasteful,\ perhaps\ (possibly\ problematic\ if\ variable\ write\ traces\ are\ involved),\ but\ still\ better\ than\ most\ of\ the\ alternatives.\ \ (Perhaps\ a\ third\ argument\ to\ \[lrepeat\]\ would\ fulfill\ the\ empty-string\ filling\ requirement\ by\ accepting\ an\ initial\ list,\ and\ repeatedly\ appending\ the\ specified\ ''item''\ until\ the\ list\ contains\ at\ least\ ''count''\ words?\ \ I\ can\ imagine\ several\ occasions\ where\ that\ could\ be\ handy.)\n\n----\n\[Ed\ Hume\]:\ I\ think\ the\ syntax\ of\ lassign\ is\ not\ as\ useful\ as\ having\ the\ value\ list\ and\ the\ variable\ name\ list\ being\ of\ similar\ structure:\n\ \n\ \ \ \ \ \ vset\ \{value1\ value2\ value3\ ...\}\ \{name1\ name2\ name3\ ...\}\n\nI\ have\ provided\ an\ lset\ command\ since\ Tcl\ 7.6\ in\ my\ toolset\ which\ was\ renamed\ to\ vset\ with\ Tcl\ 8.4.\ \ Having\ both\ the\ names\ and\ values\ as\ vectors\ allows\ you\ to\ easily\ pass\ both\ to\ other\ procedures\ without\ resorting\ to\ a\ variable\ number\ of\ arguments.\ \ It\ is\ a\ common\ idiom\ to\ assign\ each\ row\ of\ table\ data\ to\ a\ list\ of\ column\ names\ and\ work\ with\ it:\n\n\ \ \ foreach\ row\ \$rows\ \{\n\ \ \ \ \ \ \ vset\ \$row\ \$cols\n\ \ \ \ \ \ \ #\ now\ each\ column\ name\ is\ defined\ with\ the\ data\ of\ the\ table\ row\n\ \ \ \ \ \ \ #\ ...\n\ \ \ \ \ \ \ \}\n\nA\ second\ significant\ advantage\ of\ this\ syntax\ is\ that\ the\ structure\ of\ the\ names\ and\ the\ values\ are\ not\ limited\ to\ vectors.\ \ The\ vset\ command\ is\ actually\ a\ simplified\ case\ of\ the\ rset\ command\ which\ does\ a\ recursive\ set\ of\ nested\ data\ structures:\n\n\ \ \ rset\ \{1\ 2\ 3\}\ \{a\ b\ c\}\n\ \ \ #\ \$a\ is\ 1,\ \$b\ is\ 2,\ ...\n\ \ \ rset\ \{\{1.1\ 1.2\ 1.3\}\ 2\ \{3.1\ 3.2\}\}\ \{\{a\ b\ c\}\ d\ \{e\ f\}\}\n\ \ \ #\ \$a\ is\ 1.1,\ \$b\ is\ 1.2,\ \$f\ is\ 3.2,....\n\nThe\ syntax\ of\ vset\ and\ rset\ lend\ themselves\ to\ providing\ an\ optional\ third\ argument\ to\ provide\ default\ values\ in\ the\ case\ where\ empty\ values\ are\ not\ desired.\ So\ this\ is\ a\ cleaner\ implementation\ of\ frederic's\ lassign-with-defaults\ -\ the\ defaults\ values\ can\ have\ the\ usual\ empty\ string\ default.\n\nNow\ that\ Tcl\ has\ the\ expansion\ operator\ the\ difference\ between\ lassign\ and\ vset\ is\ not\ as\ important\ as\ it\ was,\ but\ I\ do\ think\ vset\ is\ a\ lot\ more\ powerful.\n\n\[DKF\]:\ Ultimately,\ we\ went\ for\ the\ option\ that\ we\ did\ because\ that\ was\ what\ \[TclX\]\ used.\ However,\ a\ side-benefit\ is\ that\ it\ also\ makes\ compiling\ the\ command\ to\ bytecode\ much\ easier\ than\ it\ would\ have\ been\ with\ `vset`.\ (Command\ compilers\ are\ rather\ tricky\ to\ write\ when\ they\ need\ to\ parse\ apart\ arguments.)\n\n<<categories>>Category\ Command\ |\ Category\ TclX regexp2} CALL {my render lassign As\ from\ 8.5,\ \[lassign\],\ the\ \[list\]\ assignment\ command,\ is\ in\ the\ \[Tcl\]\ \[core\]\ -\ see\ \[Changes\ in\ Tcl/Tk\ 8.5\]\ and\ \[TIP\]\ 57\ \[http://purl.org/tcl/tip/57.html\].\ Prior\ to\ that,\ it\ was\ in\ the\ \[TclX\]\ \[package\].\n`lassign`\ became\ a\ built-in\ command\ in\ Tcl\ \[Changes\ in\ Tcl/Tk\ 8.5%|%8.5\].\n\n**\ Documentation\ **\nIt\ takes\ a\ ''list''\ and\ assigns\ the\ values\ from\ it\ to\ each\ of\ the\ variables\ given\ by\ ''varName''\ in\ turn.\ Any\ values\ from\ the\ ''list''\ that\ are\ not\ assigned\ are\ returned\ as\ a\ sublist.\ Thus:\n===\nset\ end\ \[\['''lassign'''\ \{1\ 2\ 3\ 4\ 5\}\ a\ b\ c\]\]\n===\nwill\ set\ `\$a`\ to\ `1`,\ `\$b`\ to\ `2`,\ `\$c`\ to\ `3`,\ and\ `\$end`\ to\ “`4\ 5`”.\n<<br>>\nAny\ extra\ variables\ that\ don't\ match\ up\ to\ a\ list\ element\ are\ assigned\ the\ empty\ string.\n\nSee\ \[http://purl.org/tcl/home/man/tcl8.5/TclCmd/lassign.htm%|%the\ manual\ page%|%\]\ for\ full\ documentation.\n\n----\n\[TclX\]\ has\ supplied\ lassign\ since\ the\ early\ \[\[or\ mid-?\]\]\ '90s.\n\ \ \ \[http://www.tcl.tk/man/tcl/TclCmd/lassign.htm%|%official\ reference\]:\ \ \ \nExample\ usage:\n\ \ \ \ lassign\ \{value1\ value2\}\ variable1\ variable2\nin\ place\ of\n\ \ \ \ set\ variable1\ value1\n\ \ \ \ set\ variable2\ value2\n\ \ \ \[TIP\]\ \[http://purl.org/tcl/tip/57.html%|%57\]:\ \ \ proposed\ making\ the\ \[TclX\]\ `lassign`\ command\ a\ built-in\ Tcl\ command\ \n**\ Description\ **\n----\nActually,\ note\ that\ lassign\ takes\ a\ list\ and\ assigns\ each\ element\ to\ a\ variable.\ \ Thus,\ while\ the\ above\ is\ true,\ the\ list\ of\ values\ can\ have\ dozens\ of\ elements.\n\nFor\ example:\n\n\ \ \ lassign\ \[list\ 1\ 2\ 3\ 4\ 5\ 6\ 7\]\ variable1\ variable2\n\ \ \ puts\ \$variable1\n\ 1\n\ \ \ puts\ \$variable2\n\ 2\n`lassign`\ assigns\ values\ from\ a\ \[list\]\ to\ the\ specified\ variables,\ and\nThe\ more\ variables\ you\ supply,\ the\ more\ single\ values\ are\ assigned.\n======\n\[LV\]\ 2006\ Dec\ 06\ -\ here's\ another\ example\ of\ which\ one\ should\ be\ aware:\nwill\ set\ `\$a`\ to\ `1`,\ `\$b`\ to\ `2`,\ `\$c`\ to\ `3`,\ and\ `\$end`\ to\ `4\ 5`.\n\ %\ lassign\ \[list\ 1\ 2\]\ a\ b\ c\n\ %\ puts\ \$a\n\ 1\n\ %\ puts\ \$b\n\ 2\n\ %\ puts\ \$c\nIn\ \[lisp\]\ parlance:\n\ %\n======\nIn\ other\ words,\ note\ that\ if\ more\ variables\ are\ provided\ than\ values,\ the\nvariable\ is\ defined\ to\ be\ a\ 0\ length\ string,\ rather\ than\ either\ remaining\nundefined\ or\ retaining\ a\ previous\ value\ (if\ already\ defined).\nIf\ there\ are\ more\ ''varNames''\ than\ there\ are\ items\ in\ the\ list,\ the\ extra\n======none\n----\n''Does\ lassign\ in\ \[Tcl\]\ 8.5\ differ\ in\ any\ way\ from\ TclX's\ version?''\n%\nThey\ do\ not\ differ\ in\ any\ script-visible\ way.\ You\ call\ them\ with\ the\ same\ syntax.\ \ Same\ arguments\ to\ both\ implies\ same\ results\ from\ both.\nIn\ Tcl\ prior\ to\ 8.5,\ `\[foreach\]`\ was\ used\ to\ achieve\ the\ functionality\ of\nThe\ internal\ implementation\ is\ not\ the\ same\;\ the\ new\ \[\[lassign\]\]\ in\ Tcl\ 8.5\ makes\ use\ of\ the\ \[bytecode\]\ compiler.\n======\n\[DKF\]:\ The\ new\ implementation\ is\ also\ much\ more\ heavily\ tested.\ \ I've\ a\ bit\ of\ experience\ with\ being\ paranoiac\ about\ tests\ these\ days...\ :^/\n\n\[JMN\]:\ tclX\ doesn't\ seem\ to\ use\ a\ separate\ namespace\ for\ it's\ commands\ -\ so\ if\ we\ do\ a\ 'package\ require\ tclX'\ in\ Tcl\ 8.5+,\ which\ version\ of\ a\ command\ such\ as\ lassign\ will\ end\ up\ being\ used?\ \ \n----\n\[DKF\]\ cleverly\ points\ out\ that\ lassign\ makes\ a\ \[Perl\]lish\ \[\[shift\]\]\ this\ easy:\n\ \ \ \ \ \ proc\ shift\ \{\}\ \{\n\ \ \ \ \ \ \ \ \ \ global\ argv\n\ \ \ \ \ \ \ \ \ \ set\ argv\ \[lassign\ \$argv\ v\]\n\ \ \ \ \ \ \ \ \ \ return\ \$v\n\ \ \ \ \ \ \}\nOn\ the\ other\ hand,\ \[Hemang\ Lavana\]\ observes\ that\ TclXers\ already\nhave\ \"\[lvarpop\]\ ::argv\",\ an\ exact\ synonym\ for\ \"shift\".\n\n\n\ proc\ shift\ \{\}\ \{K\ \[lindex\ \$::argv\ 0\]\ \[set\ ::argv\ \[lrange\ \$::argv\ 1\ end\]\]\}\n======\n\n\ proc\ shift\ \{\}\ \{lindex\ \$::argv\ \[set\ ::argv\ \[lrange\ \$::argv\ 1\ end\]\;\ expr\ 0\]\}\n======\n\n\n\[KPV\]\ -\ For\ those\ who\ want\ to\ use\ \[\[lassign\]\]\ before\ Tcl\ 8.5,\nand\ without\ getting\ \[TclX\],\ here's\ a\ tcl-only\nversion\ of\ lassign:\n\n\ if\ \{\[info\ procs\ lassign\]\ ==\ \"\"\}\ \{\n\ \ \ \ \ \ \ \ set\ vlen\ \[llength\ \$values\]\n\ \ \ \ \ \ \ \ set\ alen\ \[llength\ \$args\]\n\n\ \ \ \ \ \ \ \ for\ \{set\ i\ \$vlen\}\ \{\$i\ <\ \$alen\}\ \{incr\ i\}\ \{\ \;#\ Make\ lists\ equal\ length\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ uplevel\ 1\ \[list\ foreach\ \$args\ \$values\ break\]\n\ \ \ \ \ \ \ \ return\ \[lrange\ \$values\ \$alen\ end\]\n\ \ \ \ \}\n\}\n\ \}\n\[jcw\]:\ Couldn't\ resist\ rewriting\ in\ a\ style\ I\ prefer.\ \ Chaq'un\ son\ gout\ -\ a\n\[jcw\]\ -\ Couldn't\ resist\ rewriting\ in\ a\ style\ I\ prefer.\ \ Chaq'un\ son\ gout\ -\ a\ matter\ of\ taste\ -\ of\ course:\n======\n\ if\ \{\[info\ procs\ lassign\]\ ==\ \"\"\}\ \{\n\ \ \ \ \ \ \ \ while\ \{\[llength\ \$values\]\ <\ \[llength\ \$args\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ values\ \{\}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ uplevel\ 1\ \[list\ foreach\ \$args\ \$values\ break\]\n\ \ \ \ \ \ \ \ lrange\ \$values\ \[llength\ \$args\]\ end\n\ \ \ \ \}\n\}\n\ \}\n\[KPV\]:\ But\ from\ an\ efficiency\ point\ of\ view,\ you're\ calling\ `\[llength\]`\ way\ too\n\[KPV\]\ -\ But\ from\ an\ efficiency\ point\ of\ view,\ you're\ calling\ '''llength'''\nway\ too\ many\ times--every\ iteration\ through\ the\ '''while'''\ loop\ does\ two\nunnecessary\ calls.\ How\ about\ this\ version--your\ style\ but\ more\ efficient:\n======\n\ if\ \{\[info\ procs\ lassign\]\ ==\ \"\"\}\ \{\n\ \ \ \ \ \ \ \ set\ alen\ \[llength\ \$args\]\n\ \ \ \ \ \ \ \ set\ vlen\ \[llength\ \$values\]\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ while\ \{\[incr\ vlen\]\ <=\ \$alen\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ lappend\ values\ \{\}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ uplevel\ 1\ \[list\ foreach\ \$args\ \$values\ break\]\n\ \ \ \ \ \ \ \ lrange\ \$values\ \$alen\ end\n\ \ \ \ \}\n\}\n\ \}\n\[jcw\]\ interjects:\ Keith...\ are\ you\ sure\ `\[llength\]`\ is\ slower?\ (be\ sure\ to\ test\n''Keith...\ are\ you\ sure\ \[llength\]\ is\ slower?\ (be\ sure\ to\ test\ inside\ a\ \[proc\]\ body)\ -\[jcw\]''\nIt\ must\ be\ my\ assembler/C\ background\ but\ I\ see\ those\ function\ calls,\ especially\nthe\ one\ returning\ a\ constant\ value\ and\ wince.\ \nBut\ you're\ correct,\ calling\ llength\ is\ no\ slower\ than\ accessing\ a\ variable.\ It\ \nguess\ the\ byte\ compiler\ is\ optimizing\ out\ the\ actual\ call.\ \[KPV\]\n\[kpv\]\ continues:\ It\ must\ be\ my\ assembler/C\ background\ but\ I\ see\ those\ function\n\[DKF\]:\ ''\[llength\]''\ is\ indeed\ bytecoded.\n\[DKF\]:\ `\[llength\]`\ is\ indeed\ bytecoded.\n\[sbron\]\ -\ I\ see\ no\ reason\ to\ massage\ the\ values\ list\ at\ all.\ The\ \[foreach\]\ will\ do\ exactly\ the\ same\ thing\ even\ if\ the\ values\ list\ is\ shorter\ than\ the\ \[args\]\ list.\ I.e.\ this\ should\ be\ all\ that's\ needed:\n\[sbron\]:\ I\ see\ no\ reason\ to\ massage\ the\ values\ list\ at\ all.\ `\[foreach\]`\ will\ do\n\ if\ \{\[info\ procs\ lassign\]\ eq\ \"\"\}\ \{\n\ \ \ \ proc\ lassign\ \{values\ args\}\ \{\n\ \ \ \ \ \ \ \ uplevel\ 1\ \[list\ foreach\ \$args\ \$values\ break\]\n\ \ \ \ \ \ \ \ lrange\ \$values\ \[llength\ \$args\]\ end\n\ \ \ \ \}\n\ \}\n\nThis\ version\ does\ not\ work\ as\ described\ in\ the\ documentation\ for\ lassign\ for\nThis\ version\ does\ not\ work\ as\ described\ in\ the\ documentation\ for\ lassign\ for\ this\ case:\n======\n\ %\ lassign\ \[list\]\ a\ b\ c\n\ %\ set\ a\n\ can't\ read\ \"a\":\ no\ such\ variable\n\[sbron\]:\ You\ are\ right,\ I\ just\ noticed\ that\ myself\ too.\ Improved\ version:\n\[sbron\]\ -\ You\ are\ right,\ I\ just\ noticed\ that\ myself\ too.\ Improved\ version:\n======\n\ if\ \{\[info\ procs\ lassign\]\ eq\ \"\"\}\ \{\n\ \ \ \ proc\ lassign\ \{values\ args\}\ \{\n\ \ \ \ \ \ \ \ uplevel\ 1\ \[list\ foreach\ \$args\ \[linsert\ \$values\ end\ \{\}\]\ break\]\n\ \ \ \ \ \ \ \ lrange\ \$values\ \[llength\ \$args\]\ end\n\ \ \ \ \}\n\ \}\n\[AMG\]:\ I\ prefer\ to\ use\ `\[catch\]`\ to\ check\ for\ a\ command's\ existence.\ \ Not\ only\n\[sdw\]\ Shouldn't\ that\ be\ `\[\[\[info\ commands\]\ lassign\]\]`?\n======\n\[DKF\]:\ Absolutely.\ Neither\ the\ native\ Tcl\ version\ nor\ the\ TclX\ version\ are\ procedures,\ and\ both\ are\ faster\ than\ the\ scripted\ versions\ above.\n\n\[AMG\]:\ I\ prefer\ using\ \[catch\]\ to\ detect\ the\ existence\ of\ a\ command,\ since\ it\ also\ allows\ me\ to\ detect\ if\ a\ command\ supports\ an\ option\ or\ \[ensemble\]-like\ subcommand.\n\n\[Duoas\]:\ The\ \[expr\]\ 'eq'\ doesn't\ work\ with\ anything\ before\ Tcl\ 8.4.\ Also,\ you\ really\ should\ check\ against\ an\ empty\ \$args\ list.\n\n\ if\ \{\"\[info\ commands\ ::lassign\]\[info\ procs\ ::lassign\]\"\ ==\ \"\"\}\ \{\n\ \ \ \ proc\ ::lassign\ \{list\ args\}\ \{\n\ \ \ \ \ \ \ \ if\ \{\$args\ ==\ \"\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ return\ -code\ error\ \{wrong\ #\ args:\ should\ be\ \"lassign\ list\ varName\ ?varName\ ...?\"\}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ uplevel\ 1\ \[list\ foreach\ \$args\ \[linsert\ \$list\ end\ \{\}\]\ break\]\n\ \ \ \ \ \ \ \ return\ \[lrange\ \$list\ \[llength\ \$args\]\ end\]\n\ \ \ \ \}\n\ \}\n\n\ \ \ *\ The\ 'commands'\ and\ 'procs'\ tests\ against\ any\ existing\ command\ ''or''\ proc\ named\ \"lassign\".\n\ \ \ *\ The\ '=='\ is\ valid\ Tcl\ syntax\ for\ versions\ prior\ to\ 8.4.\n\ \ \ *\ The\ error\ result\ is\ identical\ to\ (8.5.5's)\ error\ result\ for\ an\ empty\ list\ of\ variable\ names.\n\ \ \ *\ I\ like\ an\ explicit\ 'return'\ --\ though\ it\ could,\ as\ above,\ be\ omitted\ if\ you\ feel\ performance\ is\ an\ issue\ on\ old\ Tcls.\nMy\ \$0.02.\n\n\[DKF\]:\ All\ procedures\ ''are''\ commands.\ Hence\ if\ \[info\ procs\]\ finds\ them,\ so\ will\ \[info\ commands\]\ (apart\ from\ a\ few\ horrid\ nuances\ that\ don't\ matter\ here).\ The\ best\ approach\ (used\ in\ the\ Tcl\ test\ suite)\ is\ to\ check\ the\ length\ of\ list\ returned\ by\ \[info\ commands\]\;\ if\ the\ command\ name\ has\ no\ glob\ metacharacters\ in\ (as\ with\ “lassign”)\ then\ that's\ going\ to\ be\ 0\ or\ 1…\n\n----\n\[CMcC\]:\ I\ may\ be\ just\ exceptionally\ grumpy\ this\ morning\ 2005/11/14\ but\ the\ behavior\ of\ supplying\ default\ empty\ values\ to\ extra\ variables\ means\ you\ can't\ distinguish\ between\ a\ trailing\ var\ with\ no\ matching\ value,\ and\ one\ with\ a\ value\ of\ \{\}.\ \ Needs\ an\ option,\ -greedy\ or\ something,\ to\ distinguish\ between\ the\ two\ cases.\ \ Oh,\ ''and''\ it\ annoys\ me\ that\ \[\[lset\]\]\ is\ already\ taken,\ because\ \[\[lassign\]\]\ doesn't\ resonate\ well\ with\ \[\[set\]\].\n\n----\n\[KS\]:\ I\ agree\ with\ CMcC\ on\ both\ counts\ -\ supplying\ a\ default\ empty\ value\ when\ no\ matching\ value\ is\ provided\ is\ bad\ form\;\ and\ \[lset\]/\[set\]\ would\ have\ been\ better\ than\ lassign/set.\ \ However,\ I\ have\ a\ few\ other\ tweaks\ I\ would\ suggest,\ then\ I'll\ tie\ it\ all\ together\ with\ code\ to\ do\ what\ I\ suggest.\ \ \n\nFirst,\ there\ is\ a\ fundamental\ assymetry\ between\ the\ set\ and\ lassign\ behaviors\ -\ set\ copies\ right\ to\ left\;\ lassign\ goes\ from\ left\ to\ right.\ \ In\ fact,\ most\ computer\ languages\ use\ the\ idiom\ of\ right\ to\ left\ for\ assignment.\ \ However,\ there\ are\ certain\ advantages\ to\ the\ left\ to\ right\ behavior\ of\ lassign\ (it\ Tcl).\ \ For\ example,\ when\ assigning\ a\ list\ of\ variables\ to\ the\ contents\ of\ args.\ \ Using\ the\ right\ to\ left\ idiom\ would\ require\ an\ \[eval\].\ \ \n\nStill,\ the\ right\ to\ left\ behavior\ also\ has\ its\ benefits.\ \ It\ allows\ you\ to\ perform\ computations\ on\ the\ values\ before\ performing\ the\ assignment.\ \ Take,\ for\ example,\ this\ definition\ of\ factorial\ (borrowed\ from\ \[Tail\ call\ optimization\]):\n\n\ \ \ \ proc\ fact0\ \{\ n\ \}\ \{\n\ \ \ \ \ \ \ \ set\ result\ 1.\n\ \ \ \ \ \ \ \ while\ \{\ \$n\ >\ 1\ \}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ result\ \[expr\ \{\ \$result\ *\ \$n\ \}\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ n\ \[expr\ \{\ \$n\ -\ 1\ \}\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ return\ \$result\n\ \ \ \ \}\n\[JMN\]:\ tclX\ doesn't\ seem\ to\ use\ a\ separate\ namespace\ for\ its\ commands\ so\ if\ we\nNow,\ with\ lassign\ (as\ is),\ we\ can\ \"improve\"\ this\ as\ follows:\n\n\ \ \ \ proc\ fact0\ \{\ n\ \}\ \{\n\ \ \ \ \ \ \ \ set\ result\ 1.\n\ \ \ \ \ \ \ \ while\ \{\ \$n\ >\ 1\ \}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ lassign\ \[list\ \[expr\ \{\ \$result\ *\ \$n\ \}\]\ \[expr\ \{\ \$n\ -\ 1\ \}\]\]\ result\ n\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ return\ \$result\n\ \ \ \ \}\n===\nI'm\ hard\ pressed\ to\ believe\ that\ this\ is\ better.\ \ However,\ if\ we\ changed\ lassign\ to\ be\ \"lassign\ vars\ args\",\ we\ can\ write\ this\ as:\n\n\ \ \ \ proc\ fact0\ \{\ n\ \}\ \{\n\ \ \ \ \ \ \ \ set\ result\ 1.\n\ \ \ \ \ \ \ \ while\ \{\ \$n\ >\ 1\ \}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ lassign\ \{result\ n\}\ \[expr\ \{\ \$result\ *\ \$n\ \}\]\ \[expr\ \{\ \$n\ -\ 1\ \}\ \]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ return\ \$result\n\ \ \ \ \}\n\nTo\ my\ eye,\ at\ least,\ this\ is\ much\ more\ readable.\ \ \n\nSo,\ I\ suggest\ that\ we\ use\ two\ functions:\ lassign\ and\ lassignr\ (the\ \"r\"\ is\ for\ \"reverse\").\ \ lassign\ would\ be\ used\ for\ the\ \"standard\"\ behavior:\ right\ to\ left.\ \ lassignr\ would\ then\ be\ used\ for\ left\ to\ right.\ \ This\ is\ backwards\ from\ the\ way\ it\ is\ defined\ above\ for\ TclX\ and\ Tcl\ 8.5.\ \ Nonetheless,\ this\ behavior\ aligns\ better\ with\ our\ training\ and\ intuition.\ \ \n\nAlso,\ this\ provides\ a\ couple\ of\ other\ benefits.\ \ First,\ the\ parallel\ to\ set\ is\ much\ more\ obvious.\ \ lassign\ and\ set\ both\ copy\ from\ right\ to\ left\ (of\ course,\ we\ are\ still\ left\ with\ the\ assymetry\ in\ their\ names\ -\ I'll\ get\ to\ that\ later).\ \ And,\ we\ can\ now\ see\ why\ assigning\ an\ empty\ string\ to\ a\ variable\ which\ doesn't\ have\ a\ value\ supplied\ is\ bad\ form\;\ this\ is\ not\ what\ set\ does!\ \ If\ you\ enter\ \"set\ a\"\ you\ get\ the\ value\ of\ \"a\",\ you\ don't\ assign\ the\ empty\ string\ to\ \"a\".\ \ lassign\ should\ not\ either.\ \ If\ you\ want\ to\ assign\ the\ empty\ string\ using\ set\ you\ would\ enter:\n\n\ \ \ \ set\ a\ \{\}\n\nWith\ lassign,\ you\ would\ do\ something\ similar:\n\n\ \ \ \ lassign\ \{a\ b\ c\}\ 1\ \{\}\n\nHere,\ \"a\"\ gets\ \"1\",\ \"b\"\ gets\ the\ empty\ string,\ and\ c\ is\ not\ touched.\ \ This\ behavior\ parallels\ that\ of\ set\ nicely.\ \ Except\ that\ set\ returns\ the\ value\ set\;\ lassign\ does\ not.\ \ lassign\ returns\ \"unused\"\ values.\ \ So,\ let's\ take\ another\ step\ in\ that\ direction\;\ we'll\ have\ lassign\ and\ lassignr\ return\ the\ \"used\"\ values\ instead.\ \ \n\nBut,\ this\ destroys\ a\ nice\ property\ of\ lassign.\ \ Can\ we\ recover\ that\ property?\ \ Almost.\ \ We\ can\ do\ what\ \"proc\"\ does\;\ we\ can\ use\ the\ \"args\"\ variable\ name\ to\ indicate\ a\ variable\ that\ sucks\ up\ all\ the\ remaining\ items.\ \ So,\ now\ we\ get:\n\n\ \ \ \ lassign\ \{a\ b\ args\}\ 1\ 2\ 3\ 4\ 5\ 6\n\n\"a\"\ gets\ \"1\",\ \"b\"\ gets\ \"2\",\ and\ args\ gets\ \{3\ 4\ 5\ 6\}.\ \ Of\ course,\ we\ would\ make\ lassignr\ work\ similarly:\n\n\ \ \ \ lassignr\ \{1\ 2\ 3\ 4\ 5\ 6\}\ a\ b\ args\n\nBut,\ now\ that\ we\ have\ one\ of\ the\ nice\ behaviors\ of\ the\ proc\ \"assignment\",\ what\ about\ that\ other\ useful\ feature:\ default\ values?\ \ We\ can\ do\ that\ as\ well.\ \ So,\ if\ a\ value\ is\ not\ provided,\ then\ the\ default\ value\ is\ used:\n\n\ \ \ \ lassign\ \{a\ \{b\ 2\}\}\ one\n\n\"b\"\ gets\ the\ value\ \"2\".\ \ This\ also\ provides\ for\ the\ assignment\ of\ an\ empty\ list\ to\ a\ variable\ if\ the\ value\ is\ not\ provided.\ \ So,\ those\ who\ liked\ that\ behavior\ can\ have\ their\ wish\ as\ well:\n\n\ \ \ \ lassign\ \{a\ \{b\ \{\}\}\}\ one\n\nBut,\ simple\ defaults\ are\ not\ always\ adequate.\ \ This\ only\ provides\ for\ constants\;\ if\ something\ beyond\ that\ is\ required,\ then\ explicit\ lists\ are\ needed.\ \ For\ example:\n\n\ \ \ \ lassign\ \[list\ a\ \[list\ b\ \$defaultb\]\]\ one\n\nThis\ gets\ to\ be\ ugly.\ \ So,\ we\ make\ one\ more\ provision:\ we\ allow\ variable\ references\ within\ the\ defaults:\ \ \n\n\ \ \ \ lassign\ \{a\ \{b\ \$defaultb\}\}\ one\n\nNow,\ this\ really\ begins\ to\ provide\ the\ simplicity\ and\ power\ that\ we\ should\ expect\ from\ a\ general\ purpose\ utility\ routine.\ \ And,\ it\ parallels\ other\ behaviors\ within\ Tcl\ (proc\ and\ set)\ well\ so\ that\ it\ feels\ natural.\ \ \n\nBut,\ we're\ still\ left\ with\ this\ lassign/set\ dichotomy.\ \ We\ can't\ easily\ rename\ \"lassign\"\ to\ be\ \"lset\"\ (without\ potentially\ breaking\ someone's\ code).\ \ But,\ notice\ that\ lassign\ now\ provides\ features\ that\ set\ does\ not.\ \ So,\ instead,\ let's\ create\ an\ assign\ procedure\ that\ provides\ these\ same\ features,\ but\ only\ for\ a\ single\ value:\n\n\ \ \ \ assign\ \{x\ 3\}\ 7\n\nSets\ x\ to\ 7.\ \ If\ no\ value\ is\ provided,\ x\ will\ be\ 3.\ \ \n\nSo,\ we\ now\ have\ three\ functions\ (assign/lassign/lassignr)\ that\ collectively\ provide\ useful\ and\ powerful\ features\ that,\ used\ wisely,\ can\ make\ your\ code\ more\ readable\ and\ maintainable.\ \ You\ could\ argue\ that\ you\ only\ \"need\"\ one\ of\ these\ (pick\ one)\ -\ the\ others\ are\ easily\ constructed\ from\ whichever\ is\ chosen.\ \ However,\ having\ all\ three\ provides\ symmetry\ and\ flexibility.\ \ \n\nI\ have\ provided\ the\ definitions\ of\ these\ functions\ below.\ \ The\ implementation\ is\ less\ interesting\ than\ the\ simple\ power\ these\ routines\ provide.\ \ I'm\ certain\ that\ many\ of\ you\ can\ improve\ these\ implementations.\ \ And,\ if\ you\ don't\ like\ my\ rationale\ on\ the\ naming\ of\ lassignr\;\ then\ you\ can\ swap\ the\ names.\ \ It's\ easy\ to\ change\ other\ aspects\ as\ well\;\ for\ example,\ if\ you\ still\ want\ lassign\ to\ return\ the\ unused\ values,\ it's\ relatively\ easy\ to\ modify\ these\ routines.\ \ \n\n\ \ \ \ proc\ assign\ \{var\ args\}\ \{\n\ \ \ \ \ \ \ \ if\ \{\ \[llength\ \$var\]\ >\ 1\ \}\ \{\ uplevel\ set\ \$var\ \}\n\ \ \ \ \ \ \ \ uplevel\ set\ \[lindex\ \$var\ 0\]\ \$args\n\ \ \ \ \}\n\ \ \ \ \n\ \ \ \ proc\ lassign\ \{vars\ args\}\ \{\n\ \ \ \ \ \ \ \ if\ \{\ (\[lindex\ \$vars\ end\]\ eq\ \"args\")\ &&\ (\[llength\ \$args\]\ >\ \[llength\ \$vars\])\ \}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ set\ last\ \[expr\ \[llength\ \$vars\]\ -\ 1\]\n\ \ \ \ \ \ \ \ \ \ \ \ set\ args\ \[lreplace\ \$args\ \$last\ end\ \[lrange\ \$args\ \$last\ end\]\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ ##\ \ This\ is\ required\ so\ that\ we\ can\ distinguish\ between\ the\ value\ \{\}\ and\ no\ value\n\ \ \ \ \ \ \ \ foreach\ val\ \$args\ \{\ lappend\ vals\ \[list\ \$val\]\ \}\n\ \ \ \ \ \ \ \ foreach\ var\ \$vars\ val\ \$vals\ \{\ lappend\ res\ \[uplevel\ assign\ \[list\ \$var\]\ \$val\]\ \}\n\ \ \ \ \ \ \ \ return\ \$res\n\ \ \ \ \}\n\n\ \ \ \ proc\ lassignr\ \{vals\ args\}\ \{\n\ \ \ \ \ \ \ \ uplevel\ lassign\ \[list\ \$args\]\ \$vals\n\ \ \ \ \}\n\n\[FM\]\ here's\ a\ quick\ way\ to\ assign\ with\ default\ value\ (using\ apply)\n======\n\ \ \ \ proc\ args\ \{spec\ list\}\ \{\n\ \ \ \ \ \ \ \ apply\ \[list\ \$spec\ \[list\ foreach\ e\ \$spec\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ uplevel\ 2\ \[list\ set\ \[lindex\ \$e\ 0\]\ \[set\ \[lindex\ \$e\ 0\]\]\]\n\ \ \ \ \ \ \ \ \}\]\]\ \{*\}\$list\n\ \ \ \ \}\n\ \ \ \ set\ L\ \[list\]\n\ \ \ \ args\ \{\{a\ 0\}\ \{b\ 0\}\ \{c\ 0\}\ args\}\ \$L\n======\n\[slebetman\]\ KS,\ your\ proposal\ seems\ to\ illustrate\ that\ you\ don't\ ''get''\ the\ idea\ of\ '''lassign'''.\ For\ several\ years\ now\ I\ have\ used\ my\ own\ homegrown\ proc\ '''unlist'''\ that\ has\ the\ exact\ same\ syntax\ and\ semantics\ of\ '''lassign'''.\ The\ semantics\ behind\ '''lassign'''\ is\ not\ like\ \[set\]\ at\ all\ but\ more\ like\ \[scan\]\ where\ the\ semantics\ in\ most\ programming\ languages\ (at\ least\ in\ C\ and\ Python)\ is\ indeed\ assignment\ from\ left\ to\ right.\ The\ general\ use\ of\ a\ ''scanning''\ function\ like\ '''lassign'''\ is\ that\ given\ an\ opaque\ list\ (one\ that\ you\ did\ not\ create)\ split\ it\ into\ individual\ variables.\n\nIf\ you\ really\ understand\ the\ semantics\ '''lassign'''\ was\ trying\ to\ achieve\ then\ you\ wouldn't\ have\ proposed\ your:\n\n\ \ \ lassign\ vars\ args\n\nTo\ achieve\ the\ semantics\ of\ '''lassign'''\ but\ with\ right\ to\ left\ assignment\ you\ should\ have\ proposed:\n\n\ \ \ lassign\ vars\ list\n\nOf\ course,\ your\ proposal\ above\ can\ work\ with\ Tcl8.5\ using\ \[\{*\}\]:\n\n\ \ \ lassign\ \{var1\ var2\ var3\}\ \{*\}\$list\n\nBut\ that\ means\ for\ 90%\ of\ cases\ where\ you\ would\ use\ '''lassign'''\ you\ will\ have\ to\ also\ use\ \{*\}.\ Actually\ Tcl8.4\ already\ has\ a\ command\ which\ does\ what\ lassign\ is\ supposed\ to\ do\ but\ with\ a\ syntax\ that\ assigns\ from\ right\ to\ left:\ \[foreach\].\ Indeed,\ my\ home-grown\ '''unlist'''\ proc\ is\ simply\ a\ wrapper\ around\ foreach\ as\ demonstrated\ by\ \[sbron\]\ above.\ With\ 8.4,\ if\ you\ want\ lassign-like\ functionality\ you\ would\ do:\n\n\ \ \ foreach\ \{var1\ var2\ var3\}\ \$list\ \{\}\n\n\n\[KS\]:\ \[slebetman\],\ you're\ right,\ I\ did\ not\ ''get''\ that\ the\ semantics\ of\ '''lassign'''\ (which\ is\ mnemonic\ for\ \"list\ assign\"\ should\ match\ those\ of\ \[scan\]\ and\ not\ \[set\]\ (which\ is\ a\ synonym\ for\ \"assign\").\ \ Most\ languages\ refer\ to\ the\ operation\ of\ putting\ a\ value\ into\ a\ variable\ as\ \"assignment\",\ and,\ with\ only\ specialized\ exception,\ this\ is\ done\ right-to-left.\ \ I'm\ certain\ that\ others\ have\ made\ this\ same\ mistake\;\ in\ fact,\ I\ count\ myself\ in\ good\ company,\ since\ the\ authors\ of\ the\ lassign\ TIP\ #57\ \[http://purl.org/tcl/tip/57.html\]\ for\ Tcl\ 8.5\ make\ the\ same\ assumption:\n\n\ \ \ \ It\ would\ be\ more\ logical\ if\ the\ developer\ could\ write\ the\ following:\n\n\ \ \ \ \ \ \ \ set\ \{x\ y\}\ \[LocateFeature\ \$featureID\]\n\n\ \ \ \ or\n\n\ \ \ \ \ \ \ \ mset\ \{x\ y\}\ \[LocateFeature\ \$featureID\]\n\nSo,\ you\ see,\ when\ TIP\ #57\ was\ written,\ the\ thinking\ was\ in\ terms\ of\ right-to-left\ semantics\ (and,\ as\ a\ synonym\ to\ \[set\]).\ \ The\ fact\ that\ they\ decided\ to\ go\ with\ the\ left-to-right\ semantics\ was\ likely\ due\ to\ the\ issue\ that\ you\ point\ out\ about\ requiring\ an\ \[eval\]\ or\ \{*\},\ not\ that\ they\ were\ thinking\ in\ terms\ of\ \[scan\].\n\nBut,\ your\ point\ does\ suggest\ that\ a\ better\ name\ for\ '''lassign'''\ with\ left-to-right\ semantics\ is\ '''lscan'''.\ \ However,\ I\ was\ not\ ignorant\ of\ the\ concern\ with\ requiring\ an\ \[eval\]\ or\ \{*\}.\ \ I\ was\ not\ proposing\ ''eliminating''\ the\ left-to-right\ semanitcs,\ but\ adding\ the\ right-to-left\ semantics.\ \ What\ was\ left\ was\ more\ a\ discussion\ of\ proper\ naming.\ \ I\ think\ that\ you\ have\ helped\ to\ show\ that\ '''lassign'''\ should\ be\ used\ for\ right-to-left\ semantics,\ and\ '''lscan'''\ for\ left-to-right.\ \ \n\nYou\ also\ did\ not\ ''get''\ that\ I\ had\ much\ more\ to\ say\ than\ simply\ whether\ '''lassign'''\ should\ be\ left-to-right\ or\ right-to-left.\ \ For\ example,\ I\ made\ a\ proposal\ to\ allow\ for\ default\ values\ to\ be\ supplied\ when\ no\ value\ is\ available\ in\ the\ scan/assignment,\ in\ the\ manner\ of\ \[proc\].\ \ \n\nThis\ is\ not\ a\ trivial\ concern.\ \ Take,\ for\ example,\ the\ behaviors\ of\ \[scan\]\ and\ \[regexp\].\ \ \[regexp\]\ assigns\ \{\}\ to\ a\ variable\ argument\ if\ there\ is\ no\ matching\ value\ in\ the\ string\ (but,\ only\ if\ the\ match\ succeeded).\ \ However,\ \[scan\]\ only\ assigns\ values\ to\ those\ variables\ for\ which\ it\ finds\ a\ match\;\ an\ unmatched\ variable\ is\ not\ touched.\ \ \n\nThis\ leads\ to\ two\ different\ idioms\ for\ providing\ default\ values.\ \ The\ following\ example,\ based\ on\ an\ example\ in\ \[http://www.tcl.tk/man/tcl8.4/TclCmd/scan.htm\],\ uses\ \[scan\]\ and\ \[regexp\]\ to\ parse\ a\ simple\ color\ specification\ of\ the\ form\ #RRGGBB,\ where\ RR,\ GG,\ and\ BB\ are\ 2-digit\ hex\ numbers.\ \ If\ a\ value\ is\ missing\ (eg,\ #5004),\ then\ it\ defaults\ to\ 80.\ \ \n\n\ \ \ \ ##\ \ Using\ \[scan\]\n\ \ \ \ set\ r\ 80\n\ \ \ \ set\ g\ 80\n\ \ \ \ set\ b\ 80\n\ \ \ \ scan\ \$rgb\ \"#%2x%2x%2x\"\ r\ g\ b\n\ \ \ \ set\ resultRgb\ \[list\ \$r\ \$g\ \$b\]\n\ \ \ \ \n\ \ \ \ ##\ \ Using\ \[regexp\]\n\ \ \ \ regexp\ \{\$#(..)?(..)?(..)?^\}\ \$rgb\ r\ g\ b\n\ \ \ \ if\ \{\ !\ \[llength\ \$r\]\ \}\ \{\ set\ r\ 80\ \}\n\ \ \ \ if\ \{\ !\ \[llength\ \$g\]\ \}\ \{\ set\ g\ 80\ \}\n\ \ \ \ if\ \{\ !\ \[llength\ \$b\]\ \}\ \{\ set\ b\ 80\ \}\n\ \ \ \ set\ resultRgb\ \[list\ \$r\ \$g\ \$b\]\n\nAs\ you\ can\ see,\ the\ idioms\ required\ are\ different\ in\ each\ case.\ \ If,\ as\ you're\ developing\ code,\ you\ start\ with\ the\ \[scan\]\ approach,\ then\ decide\ you\ need\ to\ support\ something\ more\ sophisticated\ (eg,\ you\ want\ to\ have\ decimal,\ octal,\ or\ hex\ numbers),\ then\ you\ need\ to\ remember\ to\ change\ not\ just\ the\ parsing,\ but\ the\ method\ of\ assigning\ defaults\ as\ well.\ \ \n\nNote\ that\ this\ also\ demonstrates\ again\ that\ providing\ a\ default\ value\ (eg,\ \{\})\ when\ no\ value\ is\ provided\ really\ ought\ to\ be\ defined\ by\ the\ application\ and\ not\ the\ operation.\ \ The\ method\ of\ using\ defaults\ with\ \[scan\]\ is\ more\ straightforward\ (and\ amenable\ to\ using\ \[lassign\]\ or\ \[lscan\])\ than\ the\ method\ with\ \[regexp\].\ \ \n\nThe\ solution\ that\ I\ proposed\ was\ to\ make\ applying\ defaults\ similar\ to\ the\ way\ that\ defaults\ are\ handled\ with\ \[proc\]:\ \{var\ dflt\}.\ \ In\ fact,\ I\ would\ go\ a\ step\ farther\ and\ suggest\ that\ this\ idiom\ should\ be\ available\ to\ all\ Tcl\ operations\ that\ assign\ values\ to\ variables\ (including\ \[scan\]\ and\ \[regexp\]).\ \ But,\ I\ think\ that\ this\ is\ unlikely\ to\ occur,\ and\ is\ beyond\ the\ scope\ of\ what\ I\ was\ discussing.\ \ \n\nThe\ real\ point\ of\ my\ original\ posting\ was\ to\ demonstrate\ the\ utility,\ flexibility,\ power,\ and\ readability\ or\ using\ this\ idiom.\ \ I\ think\ it's\ a\ shame\ to\ limit\ that\ idiom\ to\ \[proc\].\ \ The\ most\ general\ application\ of\ it\ is\ to\ use\ it\ for\ assignment,\ which\ is\ what\ I\ showed.\ \ \n\n\[slebetman\]:\ I\ agree\ with\ the\ defaults\ mechanism.\ Especially\ since\ we're\ so\ used\ to\ using\ it\ in\ \[proc\].\ I\ wish\ we\ have\ it\ in\ all\ commands\ that\ assigns\ values\ to\ multiple\ variables:\n\n\ \ lassign\ \$foo\ \{a\ 0\}\ \{b\ \{\}\}\ \{c\ \"none\"\}\n\ \ scan\ \$rgb\ \"#%2x%2x%2x\"\ \{r\ 80\}\ \{g\ 80\}\ \{b\ 80\}\n\ \ regexp\ \{\$#(..)?(..)?(..)?^\}\ \$rgb\ \{r\ 80\}\ \{g\ 80\}\ \{b\ 80\}\n\ \ foreach\ \{x\ \{y\ 0\}\ \{z\ 100\}\}\ \$argv\ \{..\}\n\nI\ think\ such\ commands\ should\ check\ if\ the\ variable\ it\ is\ assigning\ to\ is\ a\ pair\ of\ words\ of\ which\ the\ second\ word\ is\ the\ default\ value.\ Assigning\ an\ empty\ string\ have\ always\ seemed\ to\ me\ too\ much\ like\ the\ hackish\ NULL\ value\ trick\ in\ C\ (the\ number\ of\ times\ I\ had\ to\ restructure\ apps\ because\ the\ customer\ insisted\ that\ zero\ is\ a\ valid\ value\ and\ should\ not\ signify\ undefined...).\n\nThe\ only\ downside\ I\ can\ think\ of\ is\ that\ this\ breaks\ apps\ with\ spaces\ in\ variable\ names.\ But\ then\ again,\ most\ of\ us\ are\ used\ to\ not\ writing\ spaces\ in\ variable\ names\ and\ we\ are\ used\ to\ this\ syntax\ in\ \[proc\].\n\nBTW,\ I\ also\ think\ \[lassign\]\ is\ a\ bad\ name\ for\ this\ operation.\ It\ makes\ much\ more\ sense\ if\ we\ instead\ use\ the\ name\ \[lassign\]\ to\ mean\ '''assign\ \"things\"\ to\ a\ list'''\ which\ fits\ your\ syntax\ proposal.\ My\ personal\ preference\ is\ still\ '''unlist'''\ (when\ we\ finally\ get\ 8.5\ I'll\ be\ doing\ an\ interp\ alias\ \{\}\ unlist\ \{\}\ lassign).\ '''lscan'''\ doesn't\ sound\ right\ to\ me\ but\ '''lsplit'''\ sounds\ just\ right\ for\ '''splitting\ a\ list\ into\ individual\ variables'''.\n\n\[DKF\]:\ The\ name\ comes\ from\ \[TclX\].\ Choosing\ a\ different\ name\ or\ argument\ syntax\ to\ that\ very\ well\ known\ piece\ of\ code\ is\ not\ worth\ it\;\ just\ gratuitous\ incompatability.\n\n----\n\[fredderic\]:\ I\ really\ don't\ see\ what\ all\ the\ fuss\ is\ about.\ \ \[lassign\]\ is\ fine\ just\ the\ way\ it\ is,\ \[lset\]\ is\ already\ taken,\ anything-'''scan'''\ sounds\ like\ it\ does\ a\ heck\ of\ a\ lot\ more\ than\ just\ assigning\ words\ to\ variables,\ and\ the\ concept\ of\ \[proc\]-like\ default\ values\ just\ makes\ me\ shudder...\ \ Even\ in\ the\ definition\ of\ a\ \[proc\]!\ \ \;)\n\nSomething\ I\ ''would''\ like\ to\ see,\ is\ an\ '''lrassign'''\ that\ does\ the\ ''left-to-right''\ thing,\ and\ ''maybe''\ some\ variant\ or\ option\ to\ \[lassign\]\ that\ takes\ a\ second\ list\ of\ ''default''\ values:\n\n\ lassign-with-defs\ defaultsList\ valuesList\ ?variable\ ...?\n\nwhere\ the\ defaults\ list\ would\ be\ empty-string-extended\ to\ the\ number\ of\ variables\ given\ (any\ extra\ defaults\ would\ simply\ be\ ignored),\ the\ values\ list\ wouldn't\ (any\ extra\ values\ would\ be\ returned\ as\ per\ usual),\ so\ you'd\ end\ up\ with:\n\n\ lassign-with-defs\ \{1\ 2\ 3\}\ \{a\ \{\}\}\ w\ x\ y\ z\n\nbeing\ the\ equivalent\ of:\n\n\ set\ w\ a\ \ \ \ \;#\ from\ values\ list\n\ set\ x\ \{\}\ \ \ \;#\ also\ from\ values\ list\n\ set\ y\ 3\ \ \ \ \;#\ 3rd\ default\ value\ carried\ through\n\ set\ z\ \{\}\ \ \ \;#\ empty-string\ expanded\ defaults\n\ #\ with\ both\ arguments\ consumed,\ and\ empty\ string\ is\ returned\n\nThe\ old\ filling-with-empty-strings\ \[lassign\]\ behaviour\ would\ thus\ be\ achieved\ by\ simply\ giving\ it\ an\ empty\ default\ values\ list,\ and\ the\ whole\ thing\ would\ be\ absolutely\ fabulous.\ \ \;)\n\nOf\ course\ the\ catch,\ is\ that\ if\ you\ simply\ take\ away\ the\ filling-with-empty-strings\ behaviour\ from\ \[lassign\],\ then\ the\ defaults\ capability\ is\ created\ by\ simply\ doing\ two\ \[lassign\]s.\ \ A\ little\ wasteful,\ perhaps\ (possibly\ problematic\ if\ variable\ write\ traces\ are\ involved),\ but\ still\ better\ than\ most\ of\ the\ alternatives.\ \ (Perhaps\ a\ third\ argument\ to\ \[lrepeat\]\ would\ fulfill\ the\ empty-string\ filling\ requirement\ by\ accepting\ an\ initial\ list,\ and\ repeatedly\ appending\ the\ specified\ ''item''\ until\ the\ list\ contains\ at\ least\ ''count''\ words?\ \ I\ can\ imagine\ several\ occasions\ where\ that\ could\ be\ handy.)\n\n----\n\[Ed\ Hume\]:\ I\ think\ the\ syntax\ of\ lassign\ is\ not\ as\ useful\ as\ having\ the\ value\ list\ and\ the\ variable\ name\ list\ being\ of\ similar\ structure:\n\ \n\ \ \ \ \ \ vset\ \{value1\ value2\ value3\ ...\}\ \{name1\ name2\ name3\ ...\}\n\nI\ have\ provided\ an\ lset\ command\ since\ Tcl\ 7.6\ in\ my\ toolset\ which\ was\ renamed\ to\ vset\ with\ Tcl\ 8.4.\ \ Having\ both\ the\ names\ and\ values\ as\ vectors\ allows\ you\ to\ easily\ pass\ both\ to\ other\ procedures\ without\ resorting\ to\ a\ variable\ number\ of\ arguments.\ \ It\ is\ a\ common\ idiom\ to\ assign\ each\ row\ of\ table\ data\ to\ a\ list\ of\ column\ names\ and\ work\ with\ it:\n\n\ \ \ foreach\ row\ \$rows\ \{\n\ \ \ \ \ \ \ vset\ \$row\ \$cols\n\ \ \ \ \ \ \ #\ now\ each\ column\ name\ is\ defined\ with\ the\ data\ of\ the\ table\ row\n\ \ \ \ \ \ \ #\ ...\n\ \ \ \ \ \ \ \}\n\nA\ second\ significant\ advantage\ of\ this\ syntax\ is\ that\ the\ structure\ of\ the\ names\ and\ the\ values\ are\ not\ limited\ to\ vectors.\ \ The\ vset\ command\ is\ actually\ a\ simplified\ case\ of\ the\ rset\ command\ which\ does\ a\ recursive\ set\ of\ nested\ data\ structures:\n\n\ \ \ rset\ \{1\ 2\ 3\}\ \{a\ b\ c\}\n\ \ \ #\ \$a\ is\ 1,\ \$b\ is\ 2,\ ...\n\ \ \ rset\ \{\{1.1\ 1.2\ 1.3\}\ 2\ \{3.1\ 3.2\}\}\ \{\{a\ b\ c\}\ d\ \{e\ f\}\}\n\ \ \ #\ \$a\ is\ 1.1,\ \$b\ is\ 1.2,\ \$f\ is\ 3.2,....\n\nThe\ syntax\ of\ vset\ and\ rset\ lend\ themselves\ to\ providing\ an\ optional\ third\ argument\ to\ provide\ default\ values\ in\ the\ case\ where\ empty\ values\ are\ not\ desired.\ So\ this\ is\ a\ cleaner\ implementation\ of\ frederic's\ lassign-with-defaults\ -\ the\ defaults\ values\ can\ have\ the\ usual\ empty\ string\ default.\n\nNow\ that\ Tcl\ has\ the\ expansion\ operator\ the\ difference\ between\ lassign\ and\ vset\ is\ not\ as\ important\ as\ it\ was,\ but\ I\ do\ think\ vset\ is\ a\ lot\ more\ powerful.\n\n\[DKF\]:\ Ultimately,\ we\ went\ for\ the\ option\ that\ we\ did\ because\ that\ was\ what\ \[TclX\]\ used.\ However,\ a\ side-benefit\ is\ that\ it\ also\ makes\ compiling\ the\ command\ to\ bytecode\ much\ easier\ than\ it\ would\ have\ been\ with\ `vset`.\ (Command\ compilers\ are\ rather\ tricky\ to\ write\ when\ they\ need\ to\ parse\ apart\ arguments.)\n\n<<categories>>Category\ Command\ |\ Category\ TclX} CALL {my revision lassign} CALL {::oo::Obj1050137 process revision/lassign} CALL {::oo::Obj1050135 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