Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/eval?V=53
QUERY_STRINGV=53
CONTENT_TYPE
DOCUMENT_URI/revision/eval
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.69.58.162
REMOTE_PORT55718
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR18.220.160.216
HTTP_CF_RAY87d3e5850a6010ff-ORD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTMozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected])
HTTP_CF_CONNECTING_IP18.220.160.216
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 eval http://purl.org/tcl/home/man/tcl8.5/TclCmd/eval.htm\n\n'''NAME'''\n\neval\ -\ Evaluate\ a\ Tcl\ script\ \n**\ Synopsis\ **\n'''SYNOPSIS'''\n\n\n\n'''DESCRIPTION'''\n\n'''Eval'''\ takes\ one\ or\ more\ arguments,\ which\ together\ comprise\ a\ Tcl\ script\ containing\ one\ or\ more\ commands.\ '''Eval'''\ concatenates\ all\ its\ arguments\ in\ the\ same\ fashion\ as\ the\ \[concat\]\ command,\ passes\ the\ concatenated\ string\ to\ the\ Tcl\ interpreter\ recursively,\ and\ returns\ the\ result\ of\ that\ evaluation\ (or\ any\ error\ generated\ by\ it).\ (From:\ \[TclHelp\])\n\ \ \ \[Injection\ Attack\]:\ \ \ \nBefore\ `\[\{*\}\]`\ is\ introduced\ since\ tcl8.5,\ eval\ is\ the\ way\ to\ expand\ lists\ to\ use\ as\ arguments.\ Even\ though\ now\ pretty\ much\ replaced\ by\ `\[\{*\}\]`,\ eval\ is\ still\ used\ a\ lot\ for\ scripts\ intended\ to\ stay\ compatible\ with\ older\ versions\ of\ tcl.\n\ \ \ \[Introspection\]:\ \ \ \n<<discussion>>\n\ \ \ \[Many\ Ways\ to\ eval\]:\ \ \ \nHere's\ the\ inside\ scoop:\ \ eval\ is\ an\ old,\ old\ command,\ that's\ been\ in\ \[Tcl\]\ from\ the\ beginning.\n\ \ \ \[http://www.tcl.tk/man/tcl/TclCmd/eval.htm%|%official\ reference\]:\ \ \ \nWhat's\ really\ going\ on\ with\ eval\ is\ this,\ at\ the\ coding\ level:\ \ formally,\ eval\ is\ about\ evaluation\nof\ scripts\ (although\ note\ that,\ in\ modern\ Tcl,\ it's\ merely\ an\ abbreviation\ for\ \"\[uplevel\]\ 0\ ...\").\nThis\ makes\ one\ think\ of\ code-data\ duality,\ such\ languages\ as\ \[Lisp\]\ and\ \[Forth\],\n\"self-modifying\ programs\",\ and\ related\ esoterica.\ \ Occasionally,\ eval\ is\ used\ in\ this\ way,\nand\ it's\ very\ powerful\ and\ crucial\ to\ Tcl\ that\ this\ be\ possible.\ \ All\ the\ commands--\[bind\],\neverything\ with\ -command,\ and\ so\ on--that\ receive\ scripts\ as\ arguments\ depend\ on\ this.\n\n'''However''',\ most\ Tcl\ applications\ don't\ need\ eval\ directly\ in\ their\ own\ coding\ for\ this\ use\ at\ all.\ \ They're\ solving\ end-user\ problems,\ not\ diving\ into\ \[introspection\].\ \ Still,\ eval\ is\ pervasive\ in\ Tcl\ coding\ for\ a\ slightly\ \"dirty\"\ reason:\ it's\ how\ we\ used\ to\ expand\ arguments.\ \ (\[\{*\}\]\ is\ the\ modern\ method\ of\ expanding\ arguments.)\n\n...\ \ \[\[invoke\ Joe\ English\ posting\n\[http://groups.google.com/groups?q=argument+expansion+apply+variadic+group:comp.lang.tcl*&hl=en&lr=&ie=UTF-8&scoring=d&selm=b4qj4p016lk%40enews2.newsguy.com&rnum=1\],\nexplain\ variadic\ parameters,\ style,\ ...\]\]\ ...\n\nThat's\ the\ background\ necessary\ to\ understand\ the\ ruminations\ that\ follow.\n\n----\nUse\ of\ the\ eval\ command\ is\ considered\ \"evil\",\ dangerous\ or\ bad\ style\ by\ some\ Tcl'ers\ (because\ it\ leads\ to\ \[double\ substitution\]),\ but\ there\ are\ situations\ where\ its\ feature\ of\ removing\ one\ layer\ of\ list\ structure\ (like\ with\ concat)\ comes\ in\ just\ right.\ If\ you\ compose\ widgets\ in\ Tk,\ first\ you\ create\ them,\ then\ you\ manage\ them\ (register\ at\ a\ geometry\ manager,\ e.g.\ ''pack'').\ You\ either\ have\ to\ keep\ track\ of\ what\ widgets\ you\ created,\ and\ repeat\ that\ list\ in\ the\ pack\ command,\ or\ just\ say\n\ eval\ pack\ \[winfo\ children\ .\]\n'''eval'''\ is\ often\ used\ with\ exec,\ to\ flatten\ input\ lists:\n\ eval\ exec\ grep\ foo\ \$filelist\nbecause\ otherwise\ ''grep''\ would\ receive\ filelist\ as\ one\ long\ filename\ with\ embedded\ blanks.\ Or,\ if\ you\ want\ to\ append\ one\ list's\ elements\ to\ another:\n\ set\ thislist\ \[concat\ \$thislist\ \$thatlist\]\ \;#\ can\ also\ be\ done\ as\n\ eval\ lappend\ thislist\ \$thatlist\n\nAnother\ application\ is\ in\ building\ up\ a\ command\ in\ pieces\ (by\ appending\ to\ a\ string)\ and\ finally\ calling\n\ eval\ \$cmd\n'''`eval`'''\ concatenates\ its\ arguments\ in\ the\ same\ fashion\ as\n----\n\[\[Document\ Donal's\ (controversial?)\ \[linsert\]\ trick\ for\ pure-list\ \nevaluation.\]\]\ \ \[\[This\ is\ probably\ the\ place\ to\ mention\ \[tclguy\]'s\ndiscussion\ \n\[http://aspn.activestate.com/ASPN/Mail/Message/tcl-core/1748289\]\nof\ the\ '''truly'''\ correct\ way\ to\ build\ a\ list\ for\ \nevaluation.\]\]\n`eval`\ is\ an\ old,\ old\ command\ that's\ been\ in\ \[Tcl\]\ from\ the\ beginning.\n----\nThe\ arguments\ to\ \[\[eval\]\]\ are\ concatenated\ into\ a\ string\ to\ be\ interpreted,\ but\ this\ operation\ does\ not\ guarantee\ that\ the\ string\ will\ be\ a\ well-formed\ script\ (i.e.,\ one\ conforming\ to\ the\ Tcl\ parsing\ rules\ as\ laid\ out\ in\ the\ Tcl\ manual\ page).\n`eval`\ is\ useful\ when\ one\ wishes\ to\ generate\ a\ script\ and\ then\ interpret\ it.\nThe\ following\ script\ breaks\ because\ the\ concatenation\ keeps\ the\ newlines\ from\ the\ list's\ string\ representation,\ making\ \[\[eval\]\]\ interpret\ the\ second\ element\ as\ a\ new\ command:\n`\[if\]\ 1\ ...`,\ which\ may\ be\ \[bytecode%|%byte-compiled\],\ is\ an\ efficient\n\ \ \ %\ set\ arg\ \{a\n\ \ \ b\n\ \ \ c\n\ \ \ \}\n\ \ \ a\n\ \ \ b\n\ \ \ c\n\ \ \ %\ eval\ list\ \$arg\n\ \ \ ambiguous\ command\ name\ \"b\":\ bgerror\ binary\ break\nWhen\ using\ `eval`,\ it\ is\ very\ easy\ to\ leave\ holes\ which\ can\ be\ exploited\ to\nTo\ solve\ this,\ construct\ the\ argument\ using\ list\ primitives\ like\ \[lappend\],\ \[list\],\ etc.\ \ DKF\ says:\ \ \"list\ and\ eval\ are\ truly\ made\ for\ each\ other.\"\n`eval`\ can\ often\ be\ avoided,\ particularly\ with\ more\ modern\ recent\ versions\ of\n\n======none\n\ \ \ %\ eval\ \[linsert\ \$arg\ 0\ list\]\n\ \ \ a\ b\ c\n`\[linsert\]`\ converts\ its\ list\ argument\ to\ a\ well-formed\ list\ with\ single\n\[linsert\]\ converts\ its\ list\ argument\ to\ a\ well-formed\ list\ with\ single\ spaces\ separating\ elements,\ and\ then\ inserts\ further\ elements\ into\ it\ (if\ any\ of\ these\ elements\ contain\ newlines,\ they\ remain\ in\ the\ resulting\ string).\nIt's\ important\ to\ remember\ that\ `eval`\ works\ on\ '''strings''',\ not\ lists,\nIt's\ important\ to\ remember\ that\ \[\[eval\]\]\ works\ on\ '''strings''',\ not\ lists,\ and\ the\ rules\ for\ interpreting\ a\ string\ as\ a\ list\ are\ different\ than\ the\ rules\ for\ interpreting\ a\ string\ as\ a\ script.\n\n----\nIn\ some\ cases\ \[\[eval\]\]\ does\ work\ on\ lists\ -\ and\ its\ special.\ \ In\ particular,\ if\ eval\ is\ passed\ a\ \[pure\ list\]\ then\nit\ gets\ evaluated\ directly,\ without\ another\ round\ of\ substitution.\ \ However,\ I\ think\ the\ utility\ is\ just\ short\ of\ what\ it\ ''could''\ be.\n**\ Verbose\ Evaluation\ **\nWhen\ you\ pass\ eval\ a\ pure\ list,\ you\ can\ only\ execute\ a\ single\ command.\ \ What\ if\ we\ were\ to\ pass\ eval\ a\ list\ of\ pure\ lists\ -\ it\ should\ directly\ evaluate\ each\ of\ them,\ and\ return\ the\ value\ of\ the\ the\ last\ one\ evaluated.\nThis\ sounds\ a\ lot\ like\ progn\ in\ \[lisp\],\ and\ it\ seems\ like\ it\ would\ allow\ for\ some\ nifty\ bits\ of\ \[introspection\]\ -\ \nfor\ example,\ if\ \[info\ body\]\ returned\ a\ pure\ list-of-lists\ rather\ than\ a\ string,\ that\ could\ be\ evaluated\ directly.\ \ Or\ modified.\ \ The\ whole\ program\ becomes\ a\ list\ of\ lists.\n\nThe\ problem\ is\ how\ to\ signal\ to\ eval\ (or\ uplevel,\ namespace,\ bind,\ ...)\ that\ it\ is\ a\ list\ of\ lists\ rather\ than\ just\ a\ list.\ \ Could\ eval\ determine\ if\ its\ input\ is\ a\ pure\ list\ and\ the\ first\ argument\ of\ that\ is\ a\ pure\ list,\ then\ evaluate\ as\ progn?\n\nAnother\ place\ this\ seems\ like\ it\ could\ be\ useful:\ I\ have\ a\ pkgIndex\ file\ with\ the\ line\n\ package\ ifneeded\ tls\ 1.4\ \"\[list\ load\ \[file\ join\ \$dir\ libtls1.4.so\]\]\;\[list\ source\ \[file\ join\ \$dir\ tls.tcl\]\]\"\nwhere\ most\ of\ the\ lines\ are\ like\n\ package\ ifneeded\ tclperl\ 2.3\ \[list\ load\ \[file\ join\ \$dir\ tclperl.so\]\]\nsince\ they\ only\ need\ one\ command\;\ but\ the\ tls\ line\ needs\ two\ commands.\ \ So\ why\ can't\ it\ be\n\ package\ ifneeded\ tls\ 1.4\ \[list\ \[list\ load\ \[file\ join\ \$dir\ libtls1.4.so\]\]\ \[list\ source\ \[file\ join\ \$dir\ tls.tcl\]\]\]\n\n----\n\[RS\]\ 2004-02-06\ -\ As\ usual\ in\ Tcl,\ functionality\ you\ miss\ you\ can\ easy\ roll\ yourself.\ I\ needed\ a\ progn-like\ list\ eval\ in\ \[RPN\ again\],\ and\ did\ it\ similar\ to\ this:\n\ proc\ leval\ args\ \{\n\ \ \ \ foreach\ arg\ \$args\ \{\n\ \ \ \ \ \ \ set\ res\ \[uplevel\ 1\ \$arg\]\n\ \ \ \ \}\n\ \ \ \ set\ res\ \;#\ return\ last\ (\"n-th\")\ result,\ as\ Tcl\ evaluation\ does\n\ \}\n\n----\n\[\[Explain\ discussion\ of\ \[\{*\}\]\ for\ argument-interpolation,\ ...\]\]\n\nFor\ example,\ if\ previously\ I\ coded\ this:\n\n\ set\ f\ \[glob\ -nocomplain\ *.tcl\]\n\ #\ some\ kind\ of\ code\ that\ ensures\ that\ \$f\ has\ something\ in\ it\n\ eval\ exec\ lp\ \$f\n\nwhat\ would\ I\ code\ now?\n\ exec\ lp\ \{*\}\$f\n\n----\n\[LV\]\ I\ just\ had\ to\ copy\ this\ over\ to\ the\ wiki\ -\ it\ is\ so\ neat!\n\n\nIt\ sounds\ like\ you're\ looking\ for\ something\ similar\ to\ /bin/sh\ \"set\ -v\"\ command\nIt\ sounds\ like\ you're\ looking\ for\ something\ similar\ to\ /bin/sh\ \"set\ -v\"\ncommand\ which\ prints\ shell\ input\ lines\ as\ they\ are\ read,\ and\ \"set\ -x\"\ which\nprints\ expanded\ commands.\ \ Kind\ of\ like\ a\ verbose\ mode.\nNope.\ \ Nothing\ like\ that.\ \ But\ you\ wouldn't\ have\ to\ write\ your\ own\ shell.\ \ You\nNope.\ \ Nothing\ like\ that.\ \ But\ you\ wouldn't\ have\ to\ write\ your\ own\ shell.\nYou\ could\ walk\ through\ a\ script\ (a\ list\ of\ lines),\ and\ use\ \[info\ complete\]\nto\ decide\ how\ many\ lines\ are\ required\ to\ complete\ the\ command,\ then\ print\nboth\ the\ command\ and\ the\ command's\ results.\ \ This\ seems\ to\ work.\n======\n\ \ proc\ verbose_eval\ \{script\}\ \{\n\ \ \ \ \ \ set\ cmd\ \"\"\n\ \ \ \ \ \ foreach\ line\ \[split\ \$script\ \\n\]\ \{\n\ \ \ if\ \{\$line\ eq\ \"\"\}\ \{continue\}\n\ \ \ \ \ \ \ \ \ \ append\ cmd\ \$line\\n\n\ \ \ \ \ \ \ \ \ \ if\ \{\ \[info\ complete\ \$cmd\]\ \}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ -nonewline\ \$cmd\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ -nonewline\ \[uplevel\ 1\ \$cmd\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ cmd\ \"\"\n\ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \}\n\ \ \}\nset\ script\ \{\n\ \ set\ script\ \{\n\ \ \ \ \ \ puts\ hello\n\ \ \ \ \ \ expr\ 2.2*3\n\ \ \}\nverbose_eval\ \$script\ \n\ \ verbose_eval\ \$script\ \n\[LV\]:\ This\ proc\ is\ so\ slick!\ I\ love\ it!\n\[LV\]\ This\ proc\ is\ so\ slick!\ I\ love\ it!\n\[Lars\ H\]:\ \ Another\ approach\ to\ this\ (which\ also\ can\ see\ individual\ commands\ in\n\[Lars\ H\]:\ Another\ approach\ to\ this\ (which\ also\ can\ see\ individual\ commands\ in\ \[if\]\ branches,\ loop\ bodies,\ etc.)\ is\ to\ use\ \[trace\]s.\ Do\ we\ have\ that\ written\ down\ anywhere?\n\[AR\]\ Here\ is\ my\ proposal\ with\ traces.\ Rem:\ the\ \"noop\"\ string\ is\ some\ kind\ of\ magic\ cookie.\n----\n\[wtracy\],\ 2008-06-23:\ I\ want\ the\ commands\ I\ run\ in\ eval\ to\ have\ their\ own\ set\ of\ variables\ independently\ of\ the\ calling\ script.\ Is\ there\ some\ way\ I\ can\ hand\ eval\ a\ context\ (maybe\ as\ an\ associative\ array?).\n\n\[Lars\ H\]:\ Sounds\ like\ you\ want\ a\ \[lambda\]\ (or\ possibly\ a\ \[closure\],\ which\ is\ more\ difficult).\ If\ you're\ using\ Tcl\ 8.5,\ then\ have\ a\ look\ at\ \[apply\].\n\[wtracy\]\ 2008-06-23:\ I\ want\ the\ commands\ I\ run\ in\ eval\ to\ have\ their\ own\ set\ of\n\[RS\]\ Long\ before\ 8.5,\ you\ could\ always\ write\ a\ little\ proc\ to\ hide\ its\ local\ variables\ (x\ in\ this\ example):\n\ %\ eval\ \{proc\ \"\"\ x\ \{expr\ \$x*\$x\}\;\ \"\"\ 5\}\n\ 25\n\[Lars\ H\]:\ Sounds\ like\ you\ want\ a\ \[lambda\]\ (or\ possibly\ a\ \[closure\],\ which\ is\n\[wtracy\]:\ Thanks.\ It\ looks\ like\ apply\ is\ the\ closest\ Tcl\ feature\ to\ what\ I\ want.\n\[RS\]:\ Long\ before\ 8.5,\ you\ could\ always\ write\ a\ little\ proc\ to\ hide\ its\ local\n\[wtracy\]:\ Actually,\ it\ looks\ like\ what\ I\ *really*\ want\ is\ to\ nest\ an\ eval\ command\ inside\ of\ a\ \[namespace\]\ eval\ block.\n======none\n\[wtracy\]:\ Okay,\ for\ the\ sake\ of\ any\ lost\ soul\ that\ comes\ along\ after\ me,\ this\ is\ what\ I\ really\ wanted\ to\ do\ all\ along:\n\ >\ set\ cmd\ \{puts\ FOO\}\n\ puts\ FOO\n\ >\ namespace\ eval\ MyNameSpace\ \$cmd\n\ FOO\n\[wtracy\]:\ Thanks.\ It\ looks\ like\ `\[apply\]`\ is\ the\ closest\ Tcl\ feature\ to\ what\n\[NEM\]\ As\ mentioned,\ \[apply\]\ is\ probably\ a\ better\ choice\ in\ this\ case\ as\ it\ is\ less\ surprising\ wrt.\ variables.\ See\n\[dangers\ of\ creative\ writing\]\ for\ some\ related\ discussion.\ The\ apply\ version\ is:\n\ apply\ \{\{\}\ \{\ puts\ FOO\ \}\ ::MyNameSpace\}\nThis\ has\ the\ benefit\ of\ evaluating\ the\ code\ within\ a\ fresh\ procedure\ context,\ meaning\ all\ variables\ are\ local\nto\ that\ context\ by\ default.\ See\ also\ \[namespace\ inscope\]/\[namespace\ code\]\ and\ you\ may\ also\ like\ \[dict\ with\].\n======\n----\n**eval\ versus\ bytecode**\n\n\[AMG\]:\ It\ appears\ \[\[eval\]\]'ed\ code\ does\ not\ get\ \[bytecode\]-compiled,\ even\ when\ \[\[eval\]\]\ is\ passed\ a\ single\ brace-quoted\ argument.\ \ The\ same\ is\ true\ for\ \[\[\[uplevel\]\ 0\]\]\ and\ \[\[\[time\]\]\].\ \ \[\[\[catch\]\]\]\ and\ \[\[\[if\]\ \{1\}\]\]\ seem\ to\ be\ bytecoded.\ \ \[\{*\}\]\ also\ gets\ bytecoded,\ but\ it\ doesn't\ accept\ a\ script\ \"argument\",\ rather\ a\ single\ command\ line\ pre-chewed\ into\ an\ objv\ list.\ \ Bytecoding\ cannot\ take\ place\ when\ the\ argument\ is\ the\ product\ of\ \[\[\[list\]\]\],\ since\ the\ script\ isn't\ in\ a\ permanent\ \[Tcl_Obj\].\n\napply\ \{\{\}\ \{puts\ FOO\}\ ::MyNameSpace\}\nproc\ b\ \{\}\ \{uplevel\ 0\ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ c\ \{\}\ \{time\ \ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ d\ \{\}\ \{catch\ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ e\ \{\}\ \{if\ \{1\}\ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ f\ \{\}\ \{\ \ \ \ \ \ \ \ \ \ \ \ \{*\}\{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ g\ \{\}\ \{eval\ \ \ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ h\ \{\}\ \{uplevel\ 0\ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ i\ \{\}\ \{time\ \ \ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ j\ \{\}\ \{catch\ \ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ k\ \{\}\ \{if\ \{1\}\ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ l\ \{\}\ \{\ \ \ \ \ \ \ \{*\}\[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ m\ \{\}\ \{try\ \ \ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\na\;b\;c\;d\;e\;f\;g\;h\;i\;j\;k\;l\;m\ntime\ a\ 10\ \ \ \ \;#\ \ 80723.8\ microseconds\ per\ iteration\ -\ slow\ntime\ b\ 10\ \ \ \ \;#\ \ 65380.2\ microseconds\ per\ iteration\ -\ slow\ntime\ c\ 10\ \ \ \ \;#\ \ 66024.8\ microseconds\ per\ iteration\ -\ slow\ntime\ d\ 100\ \ \ \;#\ \ 18888.3\ microseconds\ per\ iteration\ -\ fast\ntime\ e\ 100\ \ \ \;#\ \ 18779.3\ microseconds\ per\ iteration\ -\ fast\ntime\ f\ 100\ \ \ \;#\ \ 19375.2\ microseconds\ per\ iteration\ -\ fast\ntime\ g\ 10\ \ \ \ \;#\ 319111.5\ microseconds\ per\ iteration\ -\ very\ slow\ntime\ h\ 10\ \ \ \ \;#\ 342878.4\ microseconds\ per\ iteration\ -\ very\ slow\ntime\ i\ 10\ \ \ \ \;#\ 322279.2\ microseconds\ per\ iteration\ -\ very\ slow\ntime\ j\ 10\ \ \ \ \;#\ 316939.0\ microseconds\ per\ iteration\ -\ very\ slow\ntime\ k\ 10\ \ \ \ \;#\ 321865.5\ microseconds\ per\ iteration\ -\ very\ slow\ntime\ l\ 10\ \ \ \ \;#\ 344009.5\ microseconds\ per\ iteration\ -\ very\ slow\ntime\ m\ 100\ \ \ \;#\ \ 19503.0\ microseconds\ per\ iteration\ -\ fast\n======\n\nI\ want\ single-argument\ `eval`\ functionality\ in\ my\ code,\ but\ I\ also\ want\nI\ want\ single-argument\ \[\[eval\]\]\ functionality\ in\ my\ code,\ but\ I\ also\ want\ bytecoding.\ \ \[\[catch\]\]\ has\ the\ undesirable\ side\ effect\ of\ hiding\ errors,\ so\ I\ guess\ I\ have\ to\ use\ \[\[if\ \{1\}\]\]\ which\ is\ a\ really\ weird\ idiom.\ \ Does\ anyone\ have\ any\ better\ ideas?\n\[AMG\]:\ I\ reran\ the\ tests\ and\ got\ better\ numbers.\ \ The\ current\ version\ of\ Tcl\n\[AMG\]:\ I\ reran\ the\ tests\ and\ got\ better\ numbers.\ \ The\ current\ version\ of\ Tcl\ must\ be\ faster\ than\ whatever\ I\ used\ when\ I\ first\ did\ this\ benchmark\ (I'm\ using\ the\ same\ computer).\ \ Look\ in\ the\ page\ history\ to\ see\ the\ comparison.\ \ More\ importantly,\ I\ think\ I\ found\ a\ bytecoded\ \[\[eval\]\]:\ single-argument\ \[\[\[try\]\]\].\ \ I\ added\ a\ test\ for\ it,\ and\ it\ turns\ out\ to\ be\ just\ as\ fast\ as\ the\ other\ \"fast\"\ methods.\ \ It's\ considerably\ less\ weird\ than\ \[\[if\ \{1\}\]\],\ and\ it\ doesn't\ hide\ errors.\n\[DKF\]:\ We've\ been\ focusing\ a\ bit\ more\ on\ improving\ the\ most\ cripplingly-slow\n\[DKF\]:\ We've\ been\ focusing\ a\ bit\ more\ on\ improving\ the\ most\ cripplingly-slow\ cases,\ but\ three\ execution\ modes\ still\ exist\ that\ have\ fundamentally\ different\ speeds.\ There's\ compilation\ to\ bytecode-with-local-var-table\ (which\ is\ the\ fastest\;\ the\ speed\ comes\ from\ being\ able\ to\ compile\ in\ indexes\ into\ the\ LVT\ into\ the\ generated\ bytecode,\ which\ this\ test\ is\ particularly\ sensitive\ to),\ there's\ compilation\ to\ bytecode-without-LVT\ (slower\;\ variables\ have\ to\ be\ looked\ up\ each\ time\ they're\ accessed),\ and\ there's\ interpreting\ (slowest\ by\ far).\ There's\ not\ much\ point\ in\ doing\ a\ lot\ of\ comparison\ between\ the\ three\;\ they\ all\ exist\ for\ a\ reason.\ (We\ could\ make\ straight\ '''eval'''/'''\[uplevel\]\ 0'''\ of\ constant\ arguments\ work\ at\ full\ speed,\ but\ we\ see\ no\ reason\ to\ bother\ given\ how\ rare\ they\ are\ in\ real\ code,\ and\ it's\ better\ that\ \[time\]\ is\ kept\ simple\ anyway.)\ You\ can\ usually\ tell\ what\ sort\ of\ class\ of\ speed\ you're\ going\ to\ get\ by\ using\ \[tcl::unsupported::disassemble\]\ to\ look\ at\ the\ bytecode\ to\ see\ whether\ variables\ are\ accessed\ by\ index\ or\ by\ name,\ or\ whether\ everything's\ done\ by\ just\ building\ arguments\ and\ invoking\ “normal”\ commands.\n\[Twylite\]\ 2012-08-24:\ \ I've\ been\ optimising\ some\ control\ constructs\ and\ was\n\[Twylite\]\ (2012/08/24):\ I've\ been\ optimising\ some\ control\ constructs\ and\ was\ trying\ to\ understand\ the\ performance\ of\ various\ combinations\ of\ uplevel,\ tailcall,\ catch\ and\ try.\ \ Along\ the\ way\ I\ found\ \[AMG\]'s\ performance\ figures,\ and\ have\ updated\ them\ with\ some\ new\ ones:\n======\n#\ Fast\ (prefix\ f)\nproc\ f_baseline\ \ \ \ \ \ \ \{\}\ \{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\ \}\nproc\ f_catch\ \ \ \ \ \ \ \ \ \ \{\}\ \{catch\ \ \ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ f_catch\ \ \ \ \ \ \ \ \ \ \{\}\ \{catch\ \ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ f_if_1\ \ \ \ \ \ \ \ \ \ \ \{\}\ \{if\ \{1\}\ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ f_expand\ \ \ \ \ \ \ \ \ \{\}\ \{\ \ \ \ \ \ \ \ \ \ \ \ \ \{*\}\{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ f_try\ \ \ \ \ \ \ \ \ \ \ \ \{\}\ \{try\ \ \ \ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ f_time_apply\ \ \ \ \ \{\}\ \{time\ \{apply\ \{\{\}\ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\}\}\n#\ Medium\ (prefix\ m)\ \ \ \ \ \ \ \ \ \ \ \ \ \nproc\ m_eval\ \ \ \ \ \ \ \ \ \ \ \{\}\ \{eval\ \ \ \ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ m_eval\ \ \ \ \ \ \ \ \ \ \ \{\}\ \{eval\ \ \ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ m_uplevel_0\ \ \ \ \ \ \{\}\ \{uplevel\ 0\ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ m_time\ \ \ \ \ \ \ \ \ \ \ \{\}\ \{time\ \ \ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ m_tailcall_try\ \ \ \{\}\ \{tailcall\ \ \ \ try\ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ m_catch_uplvl_1\ \ \{\}\ \{\ \ \ \ \ \ \ set\ body\ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\ \;\ catch\ \{\ uplevel\ 1\ \$body\ \}\ \}\ \ \nproc\ m_uplvl_1_catch\ \ \{\}\ \{\ \ \ \ \ \ \ set\ body\ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\ \;\ uplevel\ 1\ \[list\ catch\ \$body\]\ \}\ \ \n#\ Slow\ (prefix\ s)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \nproc\ s_eval_list\ \ \ \ \ \ \{\}\ \{eval\ \ \ \ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ s_uplevel_0_list\ \{\}\ \{uplevel\ 0\ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ s_time_list\ \ \ \ \ \ \{\}\ \{time\ \ \ \ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ s_catch_list\ \ \ \ \ \{\}\ \{catch\ \ \ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ s_if_1_list\ \ \ \ \ \ \{\}\ \{if\ 1\ \ \ \ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ s_if_1_list\ \ \ \ \ \ \{\}\ \{if\ \{1\}\ \ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ s_tailcall\ \ \ \ \ \ \ \{\}\ \{tailcall\ \ \ \ \ \ \ \ \ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\ \}\n\nif\ 0\ \{\nif\ \{0\}\ \{\n\ \ set\ REPS\ \{f\ 10\ m\ 40\ s\ 100\}\ \;#\ reps\ by\ prefix\n\ \ set\ cmds\ \{f_baseline\ f_catch\ f_if_1\ f_expand\ f_try\ f_time_apply\ \n\ \ \ \ m_eval\ m_uplevel_0\ m_time\ m_tailcall_try\ m_catch_uplvl_1\ m_uplvl_1_catch\ \n\ \ \ \ s_eval_list\ s_uplevel_0_list\ s_time_list\ s_catch_list\ s_if_1_list\ \n\ \ \ \ s_expand_list\ s_tailcall\}\n\ \ \n\ \ foreach\ cmd\ \$cmds\ \{\ \$cmd\ \}\ \;#\ compile\n\ \ set\ cmdrepstimes\ \{\}\ \;\ foreach\ cmd\ \$cmds\ \{\ \;#\ time\n\ \ \ \ set\ reps\ \[dict\ get\ \$::REPS\ \[string\ index\ \$cmd\ 0\]\]\ \n\ \ \ \ lappend\ cmdrepstimes\ \[lindex\ \[time\ \$cmd\ \$reps\]\ 0\]\ \$cmd\ \$reps\ \n\ \ \}\n\ \ \n\ \ set\ mintime\ \[::tcl::mathfunc::min\ \{*\}\$times\]\n\ \ foreach\ \{t\ cmd\ reps\}\ \[lsort\ -real\ -stride\ 3\ \$cmdrepstimes\]\ \{\n\ \ \ \ puts\ \[format\ \"time\ %-16s\ \$reps\\t\;#\ %9.1f\ microseconds\ per\ iteration,\ factor\ %5.2f\"\ \\\n\ \ \ \ \ \ \$cmd\ \$t\ \[expr\ \{\ \$t\ /\ \$mintime\ \}\]\ \]\ \n\ \ \}\n\ntime\ f_time_apply\ \ \ \ \ 10\ \ \ \ \ \ \ \ \;#\ \ \ \ 4625.8\ microseconds\ per\ iteration,\ factor\ \ 1.00\ntime\ f_if_1\ \ \ \ \ \ \ \ \ \ \ 10\ \ \ \ \ \ \ \ \;#\ \ \ \ 4641.8\ microseconds\ per\ iteration,\ factor\ \ 1.00\ntime\ f_expand\ \ \ \ \ \ \ \ \ 10\ \ \ \ \ \ \ \ \;#\ \ \ \ 4645.0\ microseconds\ per\ iteration,\ factor\ \ 1.00\ntime\ f_catch\ \ \ \ \ \ \ \ \ \ 10\ \ \ \ \ \ \ \ \;#\ \ \ \ 4651.3\ microseconds\ per\ iteration,\ factor\ \ 1.00\ntime\ f_baseline\ \ \ \ \ \ \ 10\ \ \ \ \ \ \ \ \;#\ \ \ \ 4658.5\ microseconds\ per\ iteration,\ factor\ \ 1.01\ntime\ f_try\ \ \ \ \ \ \ \ \ \ \ \ 10\ \ \ \ \ \ \ \ \;#\ \ \ \ 4735.9\ microseconds\ per\ iteration,\ factor\ \ 1.02\ntime\ m_eval\ \ \ \ \ \ \ \ \ \ \ 40\ \ \ \ \ \ \ \ \;#\ \ \ 18454.3\ microseconds\ per\ iteration,\ factor\ \ 3.98\ntime\ m_uplevel_0\ \ \ \ \ \ 40\ \ \ \ \ \ \ \ \;#\ \ \ 18738.3\ microseconds\ per\ iteration,\ factor\ \ 4.04\ntime\ m_time\ \ \ \ \ \ \ \ \ \ \ 40\ \ \ \ \ \ \ \ \;#\ \ \ 19176.8\ microseconds\ per\ iteration,\ factor\ \ 4.14\ntime\ m_uplvl_1_catch\ \ 40\ \ \ \ \ \ \ \ \;#\ \ \ 21501.1\ microseconds\ per\ iteration,\ factor\ \ 4.64\ntime\ m_catch_uplvl_1\ \ 40\ \ \ \ \ \ \ \ \;#\ \ \ 21603.1\ microseconds\ per\ iteration,\ factor\ \ 4.66\ntime\ m_tailcall_try\ \ \ 40\ \ \ \ \ \ \ \ \;#\ \ \ 21698.4\ microseconds\ per\ iteration,\ factor\ \ 4.68\ntime\ s_uplevel_0_list\ 100\ \ \ \ \ \ \ \;#\ \ \ 84963.3\ microseconds\ per\ iteration,\ factor\ 18.34\ntime\ s_eval_list\ \ \ \ \ \ 100\ \ \ \ \ \ \ \;#\ \ \ 85519.3\ microseconds\ per\ iteration,\ factor\ 18.46\ntime\ s_catch_list\ \ \ \ \ 100\ \ \ \ \ \ \ \;#\ \ \ 85919.9\ microseconds\ per\ iteration,\ factor\ 18.54\ntime\ s_time_list\ \ \ \ \ \ 100\ \ \ \ \ \ \ \;#\ \ \ 85944.2\ microseconds\ per\ iteration,\ factor\ 18.55\ntime\ s_if_1_list\ \ \ \ \ \ 100\ \ \ \ \ \ \ \;#\ \ \ 87269.0\ microseconds\ per\ iteration,\ factor\ 18.84\ntime\ s_expand_list\ \ \ \ 100\ \ \ \ \ \ \ \;#\ \ \ 93096.9\ microseconds\ per\ iteration,\ factor\ 20.09\ntime\ s_tailcall\ \ \ \ \ \ \ 100\ \ \ \ \ \ \ \;#\ \ \ 94473.5\ microseconds\ per\ iteration,\ factor\ 20.39\n======\n\n\n regexp2} CALL {my render eval http://purl.org/tcl/home/man/tcl8.5/TclCmd/eval.htm\n\n'''NAME'''\n\neval\ -\ Evaluate\ a\ Tcl\ script\ \n**\ Synopsis\ **\n'''SYNOPSIS'''\n\n\n\n'''DESCRIPTION'''\n\n'''Eval'''\ takes\ one\ or\ more\ arguments,\ which\ together\ comprise\ a\ Tcl\ script\ containing\ one\ or\ more\ commands.\ '''Eval'''\ concatenates\ all\ its\ arguments\ in\ the\ same\ fashion\ as\ the\ \[concat\]\ command,\ passes\ the\ concatenated\ string\ to\ the\ Tcl\ interpreter\ recursively,\ and\ returns\ the\ result\ of\ that\ evaluation\ (or\ any\ error\ generated\ by\ it).\ (From:\ \[TclHelp\])\n\ \ \ \[Injection\ Attack\]:\ \ \ \nBefore\ `\[\{*\}\]`\ is\ introduced\ since\ tcl8.5,\ eval\ is\ the\ way\ to\ expand\ lists\ to\ use\ as\ arguments.\ Even\ though\ now\ pretty\ much\ replaced\ by\ `\[\{*\}\]`,\ eval\ is\ still\ used\ a\ lot\ for\ scripts\ intended\ to\ stay\ compatible\ with\ older\ versions\ of\ tcl.\n\ \ \ \[Introspection\]:\ \ \ \n<<discussion>>\n\ \ \ \[Many\ Ways\ to\ eval\]:\ \ \ \nHere's\ the\ inside\ scoop:\ \ eval\ is\ an\ old,\ old\ command,\ that's\ been\ in\ \[Tcl\]\ from\ the\ beginning.\n\ \ \ \[http://www.tcl.tk/man/tcl/TclCmd/eval.htm%|%official\ reference\]:\ \ \ \nWhat's\ really\ going\ on\ with\ eval\ is\ this,\ at\ the\ coding\ level:\ \ formally,\ eval\ is\ about\ evaluation\nof\ scripts\ (although\ note\ that,\ in\ modern\ Tcl,\ it's\ merely\ an\ abbreviation\ for\ \"\[uplevel\]\ 0\ ...\").\nThis\ makes\ one\ think\ of\ code-data\ duality,\ such\ languages\ as\ \[Lisp\]\ and\ \[Forth\],\n\"self-modifying\ programs\",\ and\ related\ esoterica.\ \ Occasionally,\ eval\ is\ used\ in\ this\ way,\nand\ it's\ very\ powerful\ and\ crucial\ to\ Tcl\ that\ this\ be\ possible.\ \ All\ the\ commands--\[bind\],\neverything\ with\ -command,\ and\ so\ on--that\ receive\ scripts\ as\ arguments\ depend\ on\ this.\n\n'''However''',\ most\ Tcl\ applications\ don't\ need\ eval\ directly\ in\ their\ own\ coding\ for\ this\ use\ at\ all.\ \ They're\ solving\ end-user\ problems,\ not\ diving\ into\ \[introspection\].\ \ Still,\ eval\ is\ pervasive\ in\ Tcl\ coding\ for\ a\ slightly\ \"dirty\"\ reason:\ it's\ how\ we\ used\ to\ expand\ arguments.\ \ (\[\{*\}\]\ is\ the\ modern\ method\ of\ expanding\ arguments.)\n\n...\ \ \[\[invoke\ Joe\ English\ posting\n\[http://groups.google.com/groups?q=argument+expansion+apply+variadic+group:comp.lang.tcl*&hl=en&lr=&ie=UTF-8&scoring=d&selm=b4qj4p016lk%40enews2.newsguy.com&rnum=1\],\nexplain\ variadic\ parameters,\ style,\ ...\]\]\ ...\n\nThat's\ the\ background\ necessary\ to\ understand\ the\ ruminations\ that\ follow.\n\n----\nUse\ of\ the\ eval\ command\ is\ considered\ \"evil\",\ dangerous\ or\ bad\ style\ by\ some\ Tcl'ers\ (because\ it\ leads\ to\ \[double\ substitution\]),\ but\ there\ are\ situations\ where\ its\ feature\ of\ removing\ one\ layer\ of\ list\ structure\ (like\ with\ concat)\ comes\ in\ just\ right.\ If\ you\ compose\ widgets\ in\ Tk,\ first\ you\ create\ them,\ then\ you\ manage\ them\ (register\ at\ a\ geometry\ manager,\ e.g.\ ''pack'').\ You\ either\ have\ to\ keep\ track\ of\ what\ widgets\ you\ created,\ and\ repeat\ that\ list\ in\ the\ pack\ command,\ or\ just\ say\n\ eval\ pack\ \[winfo\ children\ .\]\n'''eval'''\ is\ often\ used\ with\ exec,\ to\ flatten\ input\ lists:\n\ eval\ exec\ grep\ foo\ \$filelist\nbecause\ otherwise\ ''grep''\ would\ receive\ filelist\ as\ one\ long\ filename\ with\ embedded\ blanks.\ Or,\ if\ you\ want\ to\ append\ one\ list's\ elements\ to\ another:\n\ set\ thislist\ \[concat\ \$thislist\ \$thatlist\]\ \;#\ can\ also\ be\ done\ as\n\ eval\ lappend\ thislist\ \$thatlist\n\nAnother\ application\ is\ in\ building\ up\ a\ command\ in\ pieces\ (by\ appending\ to\ a\ string)\ and\ finally\ calling\n\ eval\ \$cmd\n'''`eval`'''\ concatenates\ its\ arguments\ in\ the\ same\ fashion\ as\n----\n\[\[Document\ Donal's\ (controversial?)\ \[linsert\]\ trick\ for\ pure-list\ \nevaluation.\]\]\ \ \[\[This\ is\ probably\ the\ place\ to\ mention\ \[tclguy\]'s\ndiscussion\ \n\[http://aspn.activestate.com/ASPN/Mail/Message/tcl-core/1748289\]\nof\ the\ '''truly'''\ correct\ way\ to\ build\ a\ list\ for\ \nevaluation.\]\]\n`eval`\ is\ an\ old,\ old\ command\ that's\ been\ in\ \[Tcl\]\ from\ the\ beginning.\n----\nThe\ arguments\ to\ \[\[eval\]\]\ are\ concatenated\ into\ a\ string\ to\ be\ interpreted,\ but\ this\ operation\ does\ not\ guarantee\ that\ the\ string\ will\ be\ a\ well-formed\ script\ (i.e.,\ one\ conforming\ to\ the\ Tcl\ parsing\ rules\ as\ laid\ out\ in\ the\ Tcl\ manual\ page).\n`eval`\ is\ useful\ when\ one\ wishes\ to\ generate\ a\ script\ and\ then\ interpret\ it.\nThe\ following\ script\ breaks\ because\ the\ concatenation\ keeps\ the\ newlines\ from\ the\ list's\ string\ representation,\ making\ \[\[eval\]\]\ interpret\ the\ second\ element\ as\ a\ new\ command:\n`\[if\]\ 1\ ...`,\ which\ may\ be\ \[bytecode%|%byte-compiled\],\ is\ an\ efficient\n\ \ \ %\ set\ arg\ \{a\n\ \ \ b\n\ \ \ c\n\ \ \ \}\n\ \ \ a\n\ \ \ b\n\ \ \ c\n\ \ \ %\ eval\ list\ \$arg\n\ \ \ ambiguous\ command\ name\ \"b\":\ bgerror\ binary\ break\nWhen\ using\ `eval`,\ it\ is\ very\ easy\ to\ leave\ holes\ which\ can\ be\ exploited\ to\nTo\ solve\ this,\ construct\ the\ argument\ using\ list\ primitives\ like\ \[lappend\],\ \[list\],\ etc.\ \ DKF\ says:\ \ \"list\ and\ eval\ are\ truly\ made\ for\ each\ other.\"\n`eval`\ can\ often\ be\ avoided,\ particularly\ with\ more\ modern\ recent\ versions\ of\n\n======none\n\ \ \ %\ eval\ \[linsert\ \$arg\ 0\ list\]\n\ \ \ a\ b\ c\n`\[linsert\]`\ converts\ its\ list\ argument\ to\ a\ well-formed\ list\ with\ single\n\[linsert\]\ converts\ its\ list\ argument\ to\ a\ well-formed\ list\ with\ single\ spaces\ separating\ elements,\ and\ then\ inserts\ further\ elements\ into\ it\ (if\ any\ of\ these\ elements\ contain\ newlines,\ they\ remain\ in\ the\ resulting\ string).\nIt's\ important\ to\ remember\ that\ `eval`\ works\ on\ '''strings''',\ not\ lists,\nIt's\ important\ to\ remember\ that\ \[\[eval\]\]\ works\ on\ '''strings''',\ not\ lists,\ and\ the\ rules\ for\ interpreting\ a\ string\ as\ a\ list\ are\ different\ than\ the\ rules\ for\ interpreting\ a\ string\ as\ a\ script.\n\n----\nIn\ some\ cases\ \[\[eval\]\]\ does\ work\ on\ lists\ -\ and\ its\ special.\ \ In\ particular,\ if\ eval\ is\ passed\ a\ \[pure\ list\]\ then\nit\ gets\ evaluated\ directly,\ without\ another\ round\ of\ substitution.\ \ However,\ I\ think\ the\ utility\ is\ just\ short\ of\ what\ it\ ''could''\ be.\n**\ Verbose\ Evaluation\ **\nWhen\ you\ pass\ eval\ a\ pure\ list,\ you\ can\ only\ execute\ a\ single\ command.\ \ What\ if\ we\ were\ to\ pass\ eval\ a\ list\ of\ pure\ lists\ -\ it\ should\ directly\ evaluate\ each\ of\ them,\ and\ return\ the\ value\ of\ the\ the\ last\ one\ evaluated.\nThis\ sounds\ a\ lot\ like\ progn\ in\ \[lisp\],\ and\ it\ seems\ like\ it\ would\ allow\ for\ some\ nifty\ bits\ of\ \[introspection\]\ -\ \nfor\ example,\ if\ \[info\ body\]\ returned\ a\ pure\ list-of-lists\ rather\ than\ a\ string,\ that\ could\ be\ evaluated\ directly.\ \ Or\ modified.\ \ The\ whole\ program\ becomes\ a\ list\ of\ lists.\n\nThe\ problem\ is\ how\ to\ signal\ to\ eval\ (or\ uplevel,\ namespace,\ bind,\ ...)\ that\ it\ is\ a\ list\ of\ lists\ rather\ than\ just\ a\ list.\ \ Could\ eval\ determine\ if\ its\ input\ is\ a\ pure\ list\ and\ the\ first\ argument\ of\ that\ is\ a\ pure\ list,\ then\ evaluate\ as\ progn?\n\nAnother\ place\ this\ seems\ like\ it\ could\ be\ useful:\ I\ have\ a\ pkgIndex\ file\ with\ the\ line\n\ package\ ifneeded\ tls\ 1.4\ \"\[list\ load\ \[file\ join\ \$dir\ libtls1.4.so\]\]\;\[list\ source\ \[file\ join\ \$dir\ tls.tcl\]\]\"\nwhere\ most\ of\ the\ lines\ are\ like\n\ package\ ifneeded\ tclperl\ 2.3\ \[list\ load\ \[file\ join\ \$dir\ tclperl.so\]\]\nsince\ they\ only\ need\ one\ command\;\ but\ the\ tls\ line\ needs\ two\ commands.\ \ So\ why\ can't\ it\ be\n\ package\ ifneeded\ tls\ 1.4\ \[list\ \[list\ load\ \[file\ join\ \$dir\ libtls1.4.so\]\]\ \[list\ source\ \[file\ join\ \$dir\ tls.tcl\]\]\]\n\n----\n\[RS\]\ 2004-02-06\ -\ As\ usual\ in\ Tcl,\ functionality\ you\ miss\ you\ can\ easy\ roll\ yourself.\ I\ needed\ a\ progn-like\ list\ eval\ in\ \[RPN\ again\],\ and\ did\ it\ similar\ to\ this:\n\ proc\ leval\ args\ \{\n\ \ \ \ foreach\ arg\ \$args\ \{\n\ \ \ \ \ \ \ set\ res\ \[uplevel\ 1\ \$arg\]\n\ \ \ \ \}\n\ \ \ \ set\ res\ \;#\ return\ last\ (\"n-th\")\ result,\ as\ Tcl\ evaluation\ does\n\ \}\n\n----\n\[\[Explain\ discussion\ of\ \[\{*\}\]\ for\ argument-interpolation,\ ...\]\]\n\nFor\ example,\ if\ previously\ I\ coded\ this:\n\n\ set\ f\ \[glob\ -nocomplain\ *.tcl\]\n\ #\ some\ kind\ of\ code\ that\ ensures\ that\ \$f\ has\ something\ in\ it\n\ eval\ exec\ lp\ \$f\n\nwhat\ would\ I\ code\ now?\n\ exec\ lp\ \{*\}\$f\n\n----\n\[LV\]\ I\ just\ had\ to\ copy\ this\ over\ to\ the\ wiki\ -\ it\ is\ so\ neat!\n\n\nIt\ sounds\ like\ you're\ looking\ for\ something\ similar\ to\ /bin/sh\ \"set\ -v\"\ command\nIt\ sounds\ like\ you're\ looking\ for\ something\ similar\ to\ /bin/sh\ \"set\ -v\"\ncommand\ which\ prints\ shell\ input\ lines\ as\ they\ are\ read,\ and\ \"set\ -x\"\ which\nprints\ expanded\ commands.\ \ Kind\ of\ like\ a\ verbose\ mode.\nNope.\ \ Nothing\ like\ that.\ \ But\ you\ wouldn't\ have\ to\ write\ your\ own\ shell.\ \ You\nNope.\ \ Nothing\ like\ that.\ \ But\ you\ wouldn't\ have\ to\ write\ your\ own\ shell.\nYou\ could\ walk\ through\ a\ script\ (a\ list\ of\ lines),\ and\ use\ \[info\ complete\]\nto\ decide\ how\ many\ lines\ are\ required\ to\ complete\ the\ command,\ then\ print\nboth\ the\ command\ and\ the\ command's\ results.\ \ This\ seems\ to\ work.\n======\n\ \ proc\ verbose_eval\ \{script\}\ \{\n\ \ \ \ \ \ set\ cmd\ \"\"\n\ \ \ \ \ \ foreach\ line\ \[split\ \$script\ \\n\]\ \{\n\ \ \ if\ \{\$line\ eq\ \"\"\}\ \{continue\}\n\ \ \ \ \ \ \ \ \ \ append\ cmd\ \$line\\n\n\ \ \ \ \ \ \ \ \ \ if\ \{\ \[info\ complete\ \$cmd\]\ \}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ -nonewline\ \$cmd\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ -nonewline\ \[uplevel\ 1\ \$cmd\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ cmd\ \"\"\n\ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \}\n\ \ \}\nset\ script\ \{\n\ \ set\ script\ \{\n\ \ \ \ \ \ puts\ hello\n\ \ \ \ \ \ expr\ 2.2*3\n\ \ \}\nverbose_eval\ \$script\ \n\ \ verbose_eval\ \$script\ \n\[LV\]:\ This\ proc\ is\ so\ slick!\ I\ love\ it!\n\[LV\]\ This\ proc\ is\ so\ slick!\ I\ love\ it!\n\[Lars\ H\]:\ \ Another\ approach\ to\ this\ (which\ also\ can\ see\ individual\ commands\ in\n\[Lars\ H\]:\ Another\ approach\ to\ this\ (which\ also\ can\ see\ individual\ commands\ in\ \[if\]\ branches,\ loop\ bodies,\ etc.)\ is\ to\ use\ \[trace\]s.\ Do\ we\ have\ that\ written\ down\ anywhere?\n\[AR\]\ Here\ is\ my\ proposal\ with\ traces.\ Rem:\ the\ \"noop\"\ string\ is\ some\ kind\ of\ magic\ cookie.\n----\n\[wtracy\],\ 2008-06-23:\ I\ want\ the\ commands\ I\ run\ in\ eval\ to\ have\ their\ own\ set\ of\ variables\ independently\ of\ the\ calling\ script.\ Is\ there\ some\ way\ I\ can\ hand\ eval\ a\ context\ (maybe\ as\ an\ associative\ array?).\n\n\[Lars\ H\]:\ Sounds\ like\ you\ want\ a\ \[lambda\]\ (or\ possibly\ a\ \[closure\],\ which\ is\ more\ difficult).\ If\ you're\ using\ Tcl\ 8.5,\ then\ have\ a\ look\ at\ \[apply\].\n\[wtracy\]\ 2008-06-23:\ I\ want\ the\ commands\ I\ run\ in\ eval\ to\ have\ their\ own\ set\ of\n\[RS\]\ Long\ before\ 8.5,\ you\ could\ always\ write\ a\ little\ proc\ to\ hide\ its\ local\ variables\ (x\ in\ this\ example):\n\ %\ eval\ \{proc\ \"\"\ x\ \{expr\ \$x*\$x\}\;\ \"\"\ 5\}\n\ 25\n\[Lars\ H\]:\ Sounds\ like\ you\ want\ a\ \[lambda\]\ (or\ possibly\ a\ \[closure\],\ which\ is\n\[wtracy\]:\ Thanks.\ It\ looks\ like\ apply\ is\ the\ closest\ Tcl\ feature\ to\ what\ I\ want.\n\[RS\]:\ Long\ before\ 8.5,\ you\ could\ always\ write\ a\ little\ proc\ to\ hide\ its\ local\n\[wtracy\]:\ Actually,\ it\ looks\ like\ what\ I\ *really*\ want\ is\ to\ nest\ an\ eval\ command\ inside\ of\ a\ \[namespace\]\ eval\ block.\n======none\n\[wtracy\]:\ Okay,\ for\ the\ sake\ of\ any\ lost\ soul\ that\ comes\ along\ after\ me,\ this\ is\ what\ I\ really\ wanted\ to\ do\ all\ along:\n\ >\ set\ cmd\ \{puts\ FOO\}\n\ puts\ FOO\n\ >\ namespace\ eval\ MyNameSpace\ \$cmd\n\ FOO\n\[wtracy\]:\ Thanks.\ It\ looks\ like\ `\[apply\]`\ is\ the\ closest\ Tcl\ feature\ to\ what\n\[NEM\]\ As\ mentioned,\ \[apply\]\ is\ probably\ a\ better\ choice\ in\ this\ case\ as\ it\ is\ less\ surprising\ wrt.\ variables.\ See\n\[dangers\ of\ creative\ writing\]\ for\ some\ related\ discussion.\ The\ apply\ version\ is:\n\ apply\ \{\{\}\ \{\ puts\ FOO\ \}\ ::MyNameSpace\}\nThis\ has\ the\ benefit\ of\ evaluating\ the\ code\ within\ a\ fresh\ procedure\ context,\ meaning\ all\ variables\ are\ local\nto\ that\ context\ by\ default.\ See\ also\ \[namespace\ inscope\]/\[namespace\ code\]\ and\ you\ may\ also\ like\ \[dict\ with\].\n======\n----\n**eval\ versus\ bytecode**\n\n\[AMG\]:\ It\ appears\ \[\[eval\]\]'ed\ code\ does\ not\ get\ \[bytecode\]-compiled,\ even\ when\ \[\[eval\]\]\ is\ passed\ a\ single\ brace-quoted\ argument.\ \ The\ same\ is\ true\ for\ \[\[\[uplevel\]\ 0\]\]\ and\ \[\[\[time\]\]\].\ \ \[\[\[catch\]\]\]\ and\ \[\[\[if\]\ \{1\}\]\]\ seem\ to\ be\ bytecoded.\ \ \[\{*\}\]\ also\ gets\ bytecoded,\ but\ it\ doesn't\ accept\ a\ script\ \"argument\",\ rather\ a\ single\ command\ line\ pre-chewed\ into\ an\ objv\ list.\ \ Bytecoding\ cannot\ take\ place\ when\ the\ argument\ is\ the\ product\ of\ \[\[\[list\]\]\],\ since\ the\ script\ isn't\ in\ a\ permanent\ \[Tcl_Obj\].\n\napply\ \{\{\}\ \{puts\ FOO\}\ ::MyNameSpace\}\nproc\ b\ \{\}\ \{uplevel\ 0\ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ c\ \{\}\ \{time\ \ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ d\ \{\}\ \{catch\ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ e\ \{\}\ \{if\ \{1\}\ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ f\ \{\}\ \{\ \ \ \ \ \ \ \ \ \ \ \ \{*\}\{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ g\ \{\}\ \{eval\ \ \ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ h\ \{\}\ \{uplevel\ 0\ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ i\ \{\}\ \{time\ \ \ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ j\ \{\}\ \{catch\ \ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ k\ \{\}\ \{if\ \{1\}\ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ l\ \{\}\ \{\ \ \ \ \ \ \ \{*\}\[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ m\ \{\}\ \{try\ \ \ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\na\;b\;c\;d\;e\;f\;g\;h\;i\;j\;k\;l\;m\ntime\ a\ 10\ \ \ \ \;#\ \ 80723.8\ microseconds\ per\ iteration\ -\ slow\ntime\ b\ 10\ \ \ \ \;#\ \ 65380.2\ microseconds\ per\ iteration\ -\ slow\ntime\ c\ 10\ \ \ \ \;#\ \ 66024.8\ microseconds\ per\ iteration\ -\ slow\ntime\ d\ 100\ \ \ \;#\ \ 18888.3\ microseconds\ per\ iteration\ -\ fast\ntime\ e\ 100\ \ \ \;#\ \ 18779.3\ microseconds\ per\ iteration\ -\ fast\ntime\ f\ 100\ \ \ \;#\ \ 19375.2\ microseconds\ per\ iteration\ -\ fast\ntime\ g\ 10\ \ \ \ \;#\ 319111.5\ microseconds\ per\ iteration\ -\ very\ slow\ntime\ h\ 10\ \ \ \ \;#\ 342878.4\ microseconds\ per\ iteration\ -\ very\ slow\ntime\ i\ 10\ \ \ \ \;#\ 322279.2\ microseconds\ per\ iteration\ -\ very\ slow\ntime\ j\ 10\ \ \ \ \;#\ 316939.0\ microseconds\ per\ iteration\ -\ very\ slow\ntime\ k\ 10\ \ \ \ \;#\ 321865.5\ microseconds\ per\ iteration\ -\ very\ slow\ntime\ l\ 10\ \ \ \ \;#\ 344009.5\ microseconds\ per\ iteration\ -\ very\ slow\ntime\ m\ 100\ \ \ \;#\ \ 19503.0\ microseconds\ per\ iteration\ -\ fast\n======\n\nI\ want\ single-argument\ `eval`\ functionality\ in\ my\ code,\ but\ I\ also\ want\nI\ want\ single-argument\ \[\[eval\]\]\ functionality\ in\ my\ code,\ but\ I\ also\ want\ bytecoding.\ \ \[\[catch\]\]\ has\ the\ undesirable\ side\ effect\ of\ hiding\ errors,\ so\ I\ guess\ I\ have\ to\ use\ \[\[if\ \{1\}\]\]\ which\ is\ a\ really\ weird\ idiom.\ \ Does\ anyone\ have\ any\ better\ ideas?\n\[AMG\]:\ I\ reran\ the\ tests\ and\ got\ better\ numbers.\ \ The\ current\ version\ of\ Tcl\n\[AMG\]:\ I\ reran\ the\ tests\ and\ got\ better\ numbers.\ \ The\ current\ version\ of\ Tcl\ must\ be\ faster\ than\ whatever\ I\ used\ when\ I\ first\ did\ this\ benchmark\ (I'm\ using\ the\ same\ computer).\ \ Look\ in\ the\ page\ history\ to\ see\ the\ comparison.\ \ More\ importantly,\ I\ think\ I\ found\ a\ bytecoded\ \[\[eval\]\]:\ single-argument\ \[\[\[try\]\]\].\ \ I\ added\ a\ test\ for\ it,\ and\ it\ turns\ out\ to\ be\ just\ as\ fast\ as\ the\ other\ \"fast\"\ methods.\ \ It's\ considerably\ less\ weird\ than\ \[\[if\ \{1\}\]\],\ and\ it\ doesn't\ hide\ errors.\n\[DKF\]:\ We've\ been\ focusing\ a\ bit\ more\ on\ improving\ the\ most\ cripplingly-slow\n\[DKF\]:\ We've\ been\ focusing\ a\ bit\ more\ on\ improving\ the\ most\ cripplingly-slow\ cases,\ but\ three\ execution\ modes\ still\ exist\ that\ have\ fundamentally\ different\ speeds.\ There's\ compilation\ to\ bytecode-with-local-var-table\ (which\ is\ the\ fastest\;\ the\ speed\ comes\ from\ being\ able\ to\ compile\ in\ indexes\ into\ the\ LVT\ into\ the\ generated\ bytecode,\ which\ this\ test\ is\ particularly\ sensitive\ to),\ there's\ compilation\ to\ bytecode-without-LVT\ (slower\;\ variables\ have\ to\ be\ looked\ up\ each\ time\ they're\ accessed),\ and\ there's\ interpreting\ (slowest\ by\ far).\ There's\ not\ much\ point\ in\ doing\ a\ lot\ of\ comparison\ between\ the\ three\;\ they\ all\ exist\ for\ a\ reason.\ (We\ could\ make\ straight\ '''eval'''/'''\[uplevel\]\ 0'''\ of\ constant\ arguments\ work\ at\ full\ speed,\ but\ we\ see\ no\ reason\ to\ bother\ given\ how\ rare\ they\ are\ in\ real\ code,\ and\ it's\ better\ that\ \[time\]\ is\ kept\ simple\ anyway.)\ You\ can\ usually\ tell\ what\ sort\ of\ class\ of\ speed\ you're\ going\ to\ get\ by\ using\ \[tcl::unsupported::disassemble\]\ to\ look\ at\ the\ bytecode\ to\ see\ whether\ variables\ are\ accessed\ by\ index\ or\ by\ name,\ or\ whether\ everything's\ done\ by\ just\ building\ arguments\ and\ invoking\ “normal”\ commands.\n\[Twylite\]\ 2012-08-24:\ \ I've\ been\ optimising\ some\ control\ constructs\ and\ was\n\[Twylite\]\ (2012/08/24):\ I've\ been\ optimising\ some\ control\ constructs\ and\ was\ trying\ to\ understand\ the\ performance\ of\ various\ combinations\ of\ uplevel,\ tailcall,\ catch\ and\ try.\ \ Along\ the\ way\ I\ found\ \[AMG\]'s\ performance\ figures,\ and\ have\ updated\ them\ with\ some\ new\ ones:\n======\n#\ Fast\ (prefix\ f)\nproc\ f_baseline\ \ \ \ \ \ \ \{\}\ \{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\ \}\nproc\ f_catch\ \ \ \ \ \ \ \ \ \ \{\}\ \{catch\ \ \ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ f_catch\ \ \ \ \ \ \ \ \ \ \{\}\ \{catch\ \ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ f_if_1\ \ \ \ \ \ \ \ \ \ \ \{\}\ \{if\ \{1\}\ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ f_expand\ \ \ \ \ \ \ \ \ \{\}\ \{\ \ \ \ \ \ \ \ \ \ \ \ \ \{*\}\{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ f_try\ \ \ \ \ \ \ \ \ \ \ \ \{\}\ \{try\ \ \ \ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ f_time_apply\ \ \ \ \ \{\}\ \{time\ \{apply\ \{\{\}\ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\}\}\n#\ Medium\ (prefix\ m)\ \ \ \ \ \ \ \ \ \ \ \ \ \nproc\ m_eval\ \ \ \ \ \ \ \ \ \ \ \{\}\ \{eval\ \ \ \ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ m_eval\ \ \ \ \ \ \ \ \ \ \ \{\}\ \{eval\ \ \ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ m_uplevel_0\ \ \ \ \ \ \{\}\ \{uplevel\ 0\ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ m_time\ \ \ \ \ \ \ \ \ \ \ \{\}\ \{time\ \ \ \ \ \ \ \ \ \ \ \ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ m_tailcall_try\ \ \ \{\}\ \{tailcall\ \ \ \ try\ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\}\nproc\ m_catch_uplvl_1\ \ \{\}\ \{\ \ \ \ \ \ \ set\ body\ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\ \;\ catch\ \{\ uplevel\ 1\ \$body\ \}\ \}\ \ \nproc\ m_uplvl_1_catch\ \ \{\}\ \{\ \ \ \ \ \ \ set\ body\ \{for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\}\ \;\ uplevel\ 1\ \[list\ catch\ \$body\]\ \}\ \ \n#\ Slow\ (prefix\ s)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \nproc\ s_eval_list\ \ \ \ \ \ \{\}\ \{eval\ \ \ \ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ s_uplevel_0_list\ \{\}\ \{uplevel\ 0\ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ s_time_list\ \ \ \ \ \ \{\}\ \{time\ \ \ \ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ s_catch_list\ \ \ \ \ \{\}\ \{catch\ \ \ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ s_if_1_list\ \ \ \ \ \ \{\}\ \{if\ 1\ \ \ \ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ s_if_1_list\ \ \ \ \ \ \{\}\ \{if\ \{1\}\ \ \ \ \ \[list\ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\]\}\nproc\ s_tailcall\ \ \ \ \ \ \ \{\}\ \{tailcall\ \ \ \ \ \ \ \ \ for\ \{set\ i\ 0\}\ \{\$i\ <\ 100000\}\ \{incr\ i\}\ \{\}\ \}\n\nif\ 0\ \{\nif\ \{0\}\ \{\n\ \ set\ REPS\ \{f\ 10\ m\ 40\ s\ 100\}\ \;#\ reps\ by\ prefix\n\ \ set\ cmds\ \{f_baseline\ f_catch\ f_if_1\ f_expand\ f_try\ f_time_apply\ \n\ \ \ \ m_eval\ m_uplevel_0\ m_time\ m_tailcall_try\ m_catch_uplvl_1\ m_uplvl_1_catch\ \n\ \ \ \ s_eval_list\ s_uplevel_0_list\ s_time_list\ s_catch_list\ s_if_1_list\ \n\ \ \ \ s_expand_list\ s_tailcall\}\n\ \ \n\ \ foreach\ cmd\ \$cmds\ \{\ \$cmd\ \}\ \;#\ compile\n\ \ set\ cmdrepstimes\ \{\}\ \;\ foreach\ cmd\ \$cmds\ \{\ \;#\ time\n\ \ \ \ set\ reps\ \[dict\ get\ \$::REPS\ \[string\ index\ \$cmd\ 0\]\]\ \n\ \ \ \ lappend\ cmdrepstimes\ \[lindex\ \[time\ \$cmd\ \$reps\]\ 0\]\ \$cmd\ \$reps\ \n\ \ \}\n\ \ \n\ \ set\ mintime\ \[::tcl::mathfunc::min\ \{*\}\$times\]\n\ \ foreach\ \{t\ cmd\ reps\}\ \[lsort\ -real\ -stride\ 3\ \$cmdrepstimes\]\ \{\n\ \ \ \ puts\ \[format\ \"time\ %-16s\ \$reps\\t\;#\ %9.1f\ microseconds\ per\ iteration,\ factor\ %5.2f\"\ \\\n\ \ \ \ \ \ \$cmd\ \$t\ \[expr\ \{\ \$t\ /\ \$mintime\ \}\]\ \]\ \n\ \ \}\n\ntime\ f_time_apply\ \ \ \ \ 10\ \ \ \ \ \ \ \ \;#\ \ \ \ 4625.8\ microseconds\ per\ iteration,\ factor\ \ 1.00\ntime\ f_if_1\ \ \ \ \ \ \ \ \ \ \ 10\ \ \ \ \ \ \ \ \;#\ \ \ \ 4641.8\ microseconds\ per\ iteration,\ factor\ \ 1.00\ntime\ f_expand\ \ \ \ \ \ \ \ \ 10\ \ \ \ \ \ \ \ \;#\ \ \ \ 4645.0\ microseconds\ per\ iteration,\ factor\ \ 1.00\ntime\ f_catch\ \ \ \ \ \ \ \ \ \ 10\ \ \ \ \ \ \ \ \;#\ \ \ \ 4651.3\ microseconds\ per\ iteration,\ factor\ \ 1.00\ntime\ f_baseline\ \ \ \ \ \ \ 10\ \ \ \ \ \ \ \ \;#\ \ \ \ 4658.5\ microseconds\ per\ iteration,\ factor\ \ 1.01\ntime\ f_try\ \ \ \ \ \ \ \ \ \ \ \ 10\ \ \ \ \ \ \ \ \;#\ \ \ \ 4735.9\ microseconds\ per\ iteration,\ factor\ \ 1.02\ntime\ m_eval\ \ \ \ \ \ \ \ \ \ \ 40\ \ \ \ \ \ \ \ \;#\ \ \ 18454.3\ microseconds\ per\ iteration,\ factor\ \ 3.98\ntime\ m_uplevel_0\ \ \ \ \ \ 40\ \ \ \ \ \ \ \ \;#\ \ \ 18738.3\ microseconds\ per\ iteration,\ factor\ \ 4.04\ntime\ m_time\ \ \ \ \ \ \ \ \ \ \ 40\ \ \ \ \ \ \ \ \;#\ \ \ 19176.8\ microseconds\ per\ iteration,\ factor\ \ 4.14\ntime\ m_uplvl_1_catch\ \ 40\ \ \ \ \ \ \ \ \;#\ \ \ 21501.1\ microseconds\ per\ iteration,\ factor\ \ 4.64\ntime\ m_catch_uplvl_1\ \ 40\ \ \ \ \ \ \ \ \;#\ \ \ 21603.1\ microseconds\ per\ iteration,\ factor\ \ 4.66\ntime\ m_tailcall_try\ \ \ 40\ \ \ \ \ \ \ \ \;#\ \ \ 21698.4\ microseconds\ per\ iteration,\ factor\ \ 4.68\ntime\ s_uplevel_0_list\ 100\ \ \ \ \ \ \ \;#\ \ \ 84963.3\ microseconds\ per\ iteration,\ factor\ 18.34\ntime\ s_eval_list\ \ \ \ \ \ 100\ \ \ \ \ \ \ \;#\ \ \ 85519.3\ microseconds\ per\ iteration,\ factor\ 18.46\ntime\ s_catch_list\ \ \ \ \ 100\ \ \ \ \ \ \ \;#\ \ \ 85919.9\ microseconds\ per\ iteration,\ factor\ 18.54\ntime\ s_time_list\ \ \ \ \ \ 100\ \ \ \ \ \ \ \;#\ \ \ 85944.2\ microseconds\ per\ iteration,\ factor\ 18.55\ntime\ s_if_1_list\ \ \ \ \ \ 100\ \ \ \ \ \ \ \;#\ \ \ 87269.0\ microseconds\ per\ iteration,\ factor\ 18.84\ntime\ s_expand_list\ \ \ \ 100\ \ \ \ \ \ \ \;#\ \ \ 93096.9\ microseconds\ per\ iteration,\ factor\ 20.09\ntime\ s_tailcall\ \ \ \ \ \ \ 100\ \ \ \ \ \ \ \;#\ \ \ 94473.5\ microseconds\ per\ iteration,\ factor\ 20.39\n======\n\n\n} CALL {my revision eval} CALL {::oo::Obj4063784 process revision/eval} CALL {::oo::Obj4063782 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