<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://www.tcl.tk/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Sun Feb 12 09:39:38 GMT 2012 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='224'>
<header><title>Add New [array] Subcommands &apos;incr&apos; and &apos;value&apos;</title><author address="mailto:peter@pdqi.com">Peter MacDonald</author><author address="mailto:rseeger00@aol.com">Robert Seeger</author><status type='project' state='draft' tclversion="8.7" vote='prior'>$Revision: 1.12 $</status><history></history><created day='28' month='sep' year='2004' /></header>
<abstract>The TIP proposes the addition to two new subcommands to the <emph style="bold">array</emph> command: <emph style="bold">incr</emph> and <emph style="bold">value</emph>. The <emph style="italic">&apos;incr</emph> subcommand would increment an element in an array. The <emph style="bold">value</emph> subcommand would query, reference, and/or initialize an array element.</abstract>
<body><section title="Rationale">
<para><tipref type="text" tip="215"/> proposed modifying the <emph style="bold">incr</emph> command to auto-initialize variables which do not exist, rather than throwing an error. After some debate, it was identified that frequency counting in arrays was the primary area of interest. In particular, the excessive use of <emph style="italic">if/info exists</emph> constructs in such code is inefficient, verbose and rather difficult to read. The addition of these two subcommands could substantially reduce the complexity of much Tcl code.</para>
</section>
<section title="Specification">
<para>Two new subcommands will be added to <emph style="bold">array</emph>, being <emph style="bold">incr</emph> and <emph style="bold">value</emph>. Both commands take an array name and an elem parameter, but, no string match is performed on elem.</para>
<subsection title="array incr">
<quote><emph style="bold">array incr</emph> <emph style="italic">var elem</emph> ?<emph style="italic">value</emph>? ?<emph style="italic">init</emph>?</quote>
<para>The <emph style="bold">array incr</emph> subcommand would increment <emph style="italic">var</emph>(<emph style="italic">elem</emph>), if it exists, by <emph style="italic">value</emph>, otherwise, initializes it to <emph style="italic">init</emph>. The default for <emph style="italic">value</emph> is 1, and the default for <emph style="italic">init</emph> is 0. The subcommand will return the new value and will support both integer and double values (based on the rules for addition in <emph style="bold">expr</emph>).</para>
</subsection>
<subsection title="array value">
<quote><emph style="bold">array value</emph> <emph style="italic">var elem</emph> ?<emph style="italic">value</emph>? ?<emph style="italic">init</emph>?</quote>
<para>The <emph style="bold">array value</emph> would just return the current contents of <emph style="italic">var</emph>(<emph style="italic">elem</emph>) if it exists, or <emph style="italic">value</emph> otherwise. If the <emph style="italic">init</emph> parameter resolves to true (as determined by <emph style="italic">Tcl_GetBooleanFromObj()</emph> of course), the variable is initialized to <emph style="italic">value</emph> if it doesn&apos;t already exist. The default for <emph style="italic">value</emph> is the empty string, and the default for <emph style="italic">init</emph> is false.</para>
</subsection>
</section>
<section title="Reference Implementation">
<para>Following is a Tcl only implementation of the <emph style="bold">incr</emph>/<emph style="bold">value</emph> subcommands:</para>
<verbatim><vline encoding='base64'>cHJvYyBBcnJheSB7Y21kIHZhciBlbGVtIHthbXQge319IHtpbml0IDB9fSB7</vline><vline encoding='base64'>ICAgIyBJbXBsZW1lbnQgdGhlIEFycmF5IHN1YmNtZHMgaW5jciBhbmQgdmFsdWUgb24gdmFyKGVsZW0pOg==</vline><vline encoding='base64'>ICAgIyAgLSBpbmNyICAgaW5jcmVtZW50IGEgdmFyaWFibGUgYnkgYW10IG9yIGluaXRpYWxpemU=</vline><vline encoding='base64'>ICAgIyAgICAgICAgICAgdG8gaW5pdCBpZiB1bmRlZmluZWQu</vline><vline encoding='base64'>ICAgIyAgLSB2YWx1ZSAgcmV0dXJuIHRoZSB2YWx1ZSBpZiBkZWZpbmVkLCBlbHNlIHJldHVybiBhbXQ=</vline><vline encoding='base64'>ICAgIyAgICAgICAgICAgaW5pdGlhbGl6aW5nIGlmIGluaXQu</vline><vline encoding='base64'>ICAgdXB2YXIgJHZhciB1dmFy</vline><vline encoding='base64'>ICAgaWYge1tzdHJpbmcgbWF0Y2ggJGNtZCogaW5jcl19IHs=</vline><vline encoding='base64'>ICAgICAgaWYgeyRhbXQgPT0ge319IHsgc2V0IGFtdCAxIH0=</vline><vline encoding='base64'>ICAgICAgaWYge1tpbmZvIGV4aXN0cyB1dmFyKCRlbGVtKV19IHs=</vline><vline encoding='base64'>ICAgICAgICAgcmV0dXJuIFtzZXQgdXZhcigkZWxlbSkgW2V4cHIgeyR1dmFyKCRlbGVtKSskYW10fV1d</vline><vline encoding='base64'>ICAgICAgfQ==</vline><vline encoding='base64'>ICAgICAgcmV0dXJuIFtzZXQgdXZhcigkZWxlbSkgJGluaXRd</vline><vline encoding='base64'>ICAgfSBlbHNlaWYge1tzdHJpbmcgbWF0Y2ggJGNtZCogdmFsdWVdfSB7</vline><vline encoding='base64'>ICAgICAgaWYge1tpbmZvIGV4aXN0cyB1dmFyKCRlbGVtKV19IHs=</vline><vline encoding='base64'>ICAgICAgICAgcmV0dXJuICR1dmFyKCRlbGVtKQ==</vline><vline encoding='base64'>ICAgICAgfQ==</vline><vline encoding='base64'>ICAgICAgaWYgeyRpbml0fSB7</vline><vline encoding='base64'>ICAgICAgICAgcmV0dXJuIFtzZXQgdXZhcigkZWxlbSkgJGFtdF0=</vline><vline encoding='base64'>ICAgICAgfQ==</vline><vline encoding='base64'>ICAgICAgcmV0dXJuICRhbXQ=</vline><vline encoding='base64'>ICAgfSBlbHNlIHs=</vline><vline encoding='base64'>ICAgICAgZXJyb3IgInVzYWdlOiBBcnJheSBpbmNyfHZhbHVlIHZhciBlbGVtID9hbXQ/ID9pbml0PyI=</vline><vline encoding='base64'>ICAgfQ==</vline><vline encoding='base64'>fQ==</vline></verbatim>
</section>
<section title="Discussion">
<itemize><item.i><para>Wangnic notes:</para><para><emph style="bold">array value</emph> <emph style="italic">var elem</emph> <emph style="bold">&quot;&quot; false</emph> can be written as <emph style="bold">array get</emph> <emph style="italic">var elem</emph></para><para>Array get returns name/value pairs. Array value returns just the value. Also if elem has a * in it, there may be multiple matches.</para></item.i><item.i><para>Hobbs notes:</para><para><tipref type="text" tip="200"/> already rejected <emph style="italic">array values</emph></para><para>A single item is returned from <emph style="italic">array value</emph>, not a list, as there is no string match on elem.</para><para>The problem domain is not list processing (which is expected to be relatively expensive), but rather frequency counting and set matching.</para></item.i><item.i><para>RHSeeger notes:</para><para>It would seem more consistant to push for the <emph style="italic">incr</emph> command to include a way to initialize a variable if it doesn&apos;t exist (as per <tipref type="text" tip="215"/> or the discussed options contained therein), rather than add an incr subcommand to array.</para><para>Being a fan or reintroducing the <emph style="italic">array values</emph> TIP (since the core mailing list indicates it was never fully rejected), I think <emph style="italic">array value</emph> might be a bit confusing, being only off by the lack of plurality. (I was one of the people pushing for <tipref type="text" tip="200"/> though, so take that aspect with a grain of salt)</para></item.i></itemize>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
</section>
</body></TIP>

