<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://www.tcl.tk/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Sat May 25 08:46:58 GMT 2013 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='157'>
<header><title>Argument Expansion with Leading {expand}</title><author address="mailto:kennykb@acm.org">Kevin B. Kenny</author><author address="mailto:peter.spjuth@space.se">Peter Spjuth</author><author address="mailto:donal.k.fellows@man.ac.uk">Donal K. Fellows</author><author address="mailto:dgp@users.sf.net">Don Porter</author><status type='project' state='final' tclversion="8.5" vote='after'>$Revision: 1.7 $</status><history></history><created day='20' month='sep' year='2003' /><obsoletes tip='144'/></header>
<abstract>This TIP proposes to add syntax in Tcl to perform argument expansion in a safe and efficient manner.</abstract>
<body><section title="Introduction">
<para>Many commands take a variable number of arguments and often you find yourself with those arguments in a list. This list must then be expanded into individual arguments to the command. This is currently done with eval:</para>
<verbatim><vline encoding='base64'>ZXZhbCBkZXN0cm95IFt3aW5mbyBjaGlsZHJlbiAuXQ==</vline></verbatim>
<para>This is a bit obscure and also very error prone when the command becomes more complex. It is also inefficient and not object safe, why something specialised in doing this would be better.</para>
</section>
<section title="Background">
<para>See also <tipref type="text" tip="103"/> and <tipref type="text" tip="144"/>. Please also see a summary of a poll of TCLCORE readers taken after <tipref type="text" tip="103"/> was rejected. <url ref="http://wiki.tcl.tk/9462"/></para>
</section>
<section title="Rationale">
<para>For examples three statements are used. This is the eval version:</para>
<verbatim><vline encoding='base64'>ZXZhbCBkZXN0cm95IFt3aW5mbyBjaGlsZHJlbiAuXQ==</vline><vline encoding='base64'>ZXZhbCBidXR0b24gLmIgJHN0ZGFyZ3MgLXRleHQgXCRteXRleHQgLWJkICRib3JkZXI=</vline><vline encoding='base64'>ZXZhbCBleGVjIFwkcHJvZyAkb3B0czEgW2dldE1vcmVvcHRzXSBcJGZpbGUxIFwkZmlsZTI=</vline></verbatim>
<para>The eval version would be even more complex if the lists that are to be expanded are not known to be pure. To be really safe the last would be:</para>
<verbatim><vline encoding='base64'>ZXZhbCBleGVjIFwkcHJvZyBbbHJhbmdlICRvcHRzMSAwIGVuZF0gW2xyYW5nZSBbZ2V0TW9yZW9wdHNdIDAgZW5kXSBcJGZpbGUxIFwkZmlsZTI=</vline></verbatim>
<para>With the proposed syntax they become:</para>
<verbatim><vline encoding='base64'>ZGVzdHJveSB7ZXhwYW5kfVt3aW5mbyBjaGlsZHJlbiAuXQ==</vline><vline encoding='base64'>YnV0dG9uIC5iIHtleHBhbmR9JHN0ZGFyZ3MgLXRleHQgJG15dGV4dCAtYmQgJGJvcmRlcg==</vline><vline encoding='base64'>ZXhlYyAkcHJvZyB7ZXhwYW5kfSRvcHRzMSB7ZXhwYW5kfVtnZXRNb3Jlb3B0c10gJGZpbGUxICRmaWxlMg==</vline></verbatim>
<para>The advantage of using syntax for this is that the command do not get obscured. In the examples destroy/button/exec is the most important information on each line and it gets to be first on the line.</para>
</section>
<section title="Specification">
<para>If a word starts with the string, &quot;{expand}&quot;, and is followed by a non whitespace character it signifies argument expansion. The leading &quot;{expand}&quot; is removed and the rest of the word is parsed and substituted as any other word. The character after the removed &quot;{expand}&quot; counts as a first character in the rules about open braces and double quotes. After substitution, the word is then parsed as a list (as if with <emph style="italic">Tcl_SplitList()</emph> or <emph style="italic">Tcl_GetListFromObj</emph>) and each element of the list is added to the command being built as a separate word with no further parsing.</para>
<para>Before executing the command any word to be expanded is treated as a list where each element becomes one separate argument to the command.</para>
<para><emph style="italic">Note 1:</emph> A word must begin with {expand} to trigger expansion which means that words like these are not expanded:</para>
<verbatim><vline encoding='base64'>Y21kICJ7ZXhwYW5kfSR0ZW1wIiBce2V4cGFuZH1bc29tZXRoaW5nXQ==</vline></verbatim>
<para><emph style="italic">Note 2:</emph> Expansion is typically most useful with words like:</para>
<verbatim><vline encoding='base64'>Y21kIHtleHBhbmR9JHZhciB7ZXhwYW5kfVtzb21lY21kICRhcmddIHtleHBhbmR9JGFycihbY21kICRhcmddKQ==</vline></verbatim>
<para>But things like this are also legal:</para>
<verbatim><vline encoding='base64'>Y21kIHtleHBhbmR9d29yZCB7ZXhwYW5kfSR4LCR5IHtleHBhbmR9W2Zvb114eVthcGFdIHtleHBhbmR9e2FwYSBiZXBhfQ==</vline></verbatim>
</section>
<section title="Motivating Examples">
<para>Many of the examples that make this TIP the way it is come from either advanced usage of commands like [exec] or from Tk.</para>
<para>Consider the case where you have lists of options for several external commands that are to be executed together in a pipeline. With expansion it becomes easy to execute such things:</para>
<verbatim><vline encoding='base64'>ZXhlYyBwcm9nMSB7ZXhwYW5kfSRvcHRsaXN0MSB8IHByb2cyIHtleHBhbmR9JG9wdGxpc3QyIHwgcHJvZzMgLXN0YXRpY09wdGlvbg==</vline></verbatim>
<para>As you can see, without expansion building this pipeline would be quite a complex task and would make what is going on much more obscure.</para>
<para>With Tk, there are many examples. Here&apos;s one from the creation of lines on a canvas:</para>
<verbatim><vline encoding='base64'>c2V0IGlkIFskY2FudiBjcmVhdGUgcG9seWdvbiB7ZXhwYW5kfSRjb29yZHMgLWZpbGwge30gXA==</vline><vline encoding='base64'>ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ZXhwYW5kfSRvcHRzIC10YWdzIHtmb28gYmFyfV0=</vline></verbatim>
<para>In this case, there is a fair amount of material before the coordinate list, some static options (which act like defaults) between the coords list and the user-supplied options list, and some further options (which act like overrides for semantically-significant bits) after that which need careful space handling. This also demonstrates why having a command with a list of expanding indices is not a good idea, since it is plain to see that ongoing maintenance might place extra non-expanding arguments in various places through the command.</para>
<para>Another example demonstrates why having commands as well as variables expanded is a good idea:</para>
<verbatim><vline encoding='base64'>bmFtZXNwYWNlIGV2YWwgbXkgew==</vline><vline encoding='base64'>ICAgdmFyaWFibGUgZGVmYXVsdHMgew==</vline><vline encoding='base64'>ICAgICAgLWJnIHdoaXRl</vline><vline encoding='base64'>ICAgICAgLWZnIGJsYWNr</vline><vline encoding='base64'>ICAgfQ==</vline><vline encoding='base64'>ICAgcHJvYyBlbnRyeSB7cGF0aCBhcmdzfSB7</vline><vline encoding='base64'>ICAgICAgdmFyaWFibGUgZGVmYXVsdHM=</vline><vline encoding='base64'>ICAgICAgOjplbnRyeSAkcGF0aCB7ZXhwYW5kfSRkZWZhdWx0cyBc</vline><vline encoding='base64'>ICAgICAgICAgICAgICAgICAgICB7ZXhwYW5kfVtwbGF0Zm9ybU9wdHMgJDo6dGNsX3BsYXRmb3JtKHBsYXRmb3JtKV0gXA==</vline><vline encoding='base64'>ICAgICAgICAgICAgICAgICAgICB7ZXhwYW5kfSRhcmdz</vline><vline encoding='base64'>ICAgfQ==</vline><vline encoding='base64'>fQ==</vline></verbatim>
<para>This illustrates why just plain [concat] doesn&apos;t work, demonstrates that having a way to do commands can be very useful, and also shows that having multiple expansion operations in a row is potentially useful.</para>
<para>A final example (deleting discontiguous ranges of characters with a particular tag) shows that this is not just useful in Tk for when creating widgets and canvas items:</para>
<verbatim><vline encoding='base64'>JHRleHQgZGVsZXRlIHtleHBhbmR9WyR0ZXh0IHRhZyByYW5nZXMgJHRhZ1RvQ2xlYW5VcF0=</vline></verbatim>
<para>In this case, the obvious alternative:</para>
<verbatim><vline encoding='base64'>Zm9yZWFjaCB7cyBlfSBbJHRleHQgdGFnIHJhbmdlcyAkdGhlVGFnXSB7ICR0ZXh0IGRlbGV0ZSAkcyAkZSB9</vline></verbatim>
<para>is wrong, because the positions of the tags move with each deletion (by contrast, the [$text delete] operation is careful in this regard.)</para>
</section>
<section title="Reference Implementation">
<para>Not done yet.</para>
</section>
<section title="Summary of Discussions">
<para>This TIP has had a long history; a great many alternatives have been proposed - two (<tipref type="text" tip="103"/> and <tipref type="text" tip="144"/>) formally.</para>
<para>In a poll of TCT members conducted by one of the authors, this version appeared to be the most preferred. Much of the discussion is summarized at <url ref="http://aspn.activestate.com/ASPN/Mail/Message/tcl-core/1805934"/> and <url ref="http://aspn.activestate.com/ASPN/Mail/Message/tcl-core/1791605"/> (much of the mailing list traffic between those two messages is devoted to discussion of this issue.)</para>
<para>An open issue remains as to which Tcl release is suitable for the implementation of this feature. The question will be resolved by voting on this TIP twice: once for 8.5 and once for 9.0</para>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
</section>
</body></TIP>
