<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://www.tcl.tk/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Thu May 17 03:29:51 GMT 2012 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='215'>
<header><title>Make [incr] Auto-Initialize Undefined Variables</title><author address="mailto:avl@logic.at">Andreas Leitgeb</author><author address="mailto:dgp@users.sf.net">Don Porter</author><status type='project' state='final' tclversion="8.5" vote='after'>$Revision: 1.11 $</status><history></history><created day='25' month='aug' year='2004' /><keyword>Tcl</keyword></header>
<abstract>Unlike <emph style="bold">append</emph> and <emph style="bold">lappend</emph>, <emph style="bold">incr</emph> currently does not auto-create yet-undefined variables. This TIP proposes to make <emph style="bold">incr</emph>&apos;s behaviour in this regard more like the aforementioned commands.</abstract>
<body><section title="Rationale">
<para>A quite common task is counting the number of occurrences of items in a given list. The usual solution is to iterate the list, and for each item, increment the associated value in a tcl-array. As of now this requires a separate step of determining the not-yet-existence and eventual initialization to 0 or alternatively <emph style="bold">catch</emph>&apos;ing errors from <emph style="bold">incr</emph> and setting the variable, if an error was raised.</para>
<para>If we instead alter <emph style="bold">incr</emph> to treat non-existant variables as if they contained the value 0, this would be more like the auto-initializing behaviour of <emph style="bold">append</emph> and <emph style="bold">lappend</emph>, and would make writing code that does this sort of summing up much easier. It is also very similar to the way that the <emph style="bold">dict incr</emph> subcommand operates.</para>
</section>
<section title="No Change for Variables that Contain Non-Integers">
<para>Just as <emph style="bold">lappend</emph> does complain if passed a variable whose value is an invalid list (e.g. a single open-brace), so it appears reasonable for <emph style="bold">incr</emph> to still throw an error if the variable contains something that is not a number.</para>
<para>The empty string is invalid as an operand for <emph style="bold">expr</emph>&apos;s integer operators, so it should remain illegal to <emph style="bold">incr</emph> an existing variable that contains an empty string.</para>
</section>
<section title="Further Special Cases">
<para>If a variable passed to incr is not yet existing, but linked to some other not-yet existing var, or if it is traced, then of course it would add flesh to that existing husk. Care should be taken that any write traces only trigger once (like for <emph style="bold">lappend</emph>), not twice (as in: for initializing and then for incrementing).</para>
</section>
<section title="Proposal">
<para>The current <emph style="bold">incr</emph> command behaves like the following proc:</para>
<verbatim><vline encoding='base64'>IHByb2MgaW5jciB7dmFyTmFtZSB7aW5jcmVtZW50IDF9fSB7</vline><vline encoding='base64'>ICAgICB1cHZhciAxICR2YXJOYW1lIHY=</vline><vline encoding='base64'>ICAgICByZXR1cm4gW3NldCB2IFtleHByIHskdiArICRpbmNyZW1lbnR9XV0gOyMgcmVhZC93cml0ZSB0cmFjZQ==</vline><vline encoding='base64'>IH0gIA==</vline></verbatim>
<para>It is proposed to make <emph style="bold">incr</emph> behave like the following modified proc:</para>
<verbatim><vline encoding='base64'>IHByb2MgaW5jciB7dmFyTmFtZSB7aW5jcmVtZW50IDF9fSB7</vline><vline encoding='base64'>ICAgICB1cHZhciAxICR2YXJOYW1lIHY=</vline><vline encoding='base64'>ICAgICBzZXQgY29kZSBbY2F0Y2gge3NldCB2fSB2YWx1ZV0gOyMgcmVhZCB0cmFjZQ==</vline><vline encoding='base64'>ICAgICBpZiB7JGNvZGV9IHs=</vline><vline encoding='base64'>ICAgICAgICAgcmV0dXJuIFtzZXQgdiAkaW5jcmVtZW50XSAgOyMgd3JpdGUgdHJhY2U=</vline><vline encoding='base64'>ICAgICB9</vline><vline encoding='base64'>ICAgICByZXR1cm4gW3NldCB2IFtleHByIHskdmFsdWUgKyAkaW5jcmVtZW50fV1dIDsjIHdyaXRlIHRyYWNl</vline><vline encoding='base64'>IH0gIA==</vline></verbatim>
<para>Please note these example procs are meant to illustrate the proposed change only. They do not fully reflect the exact function of <emph style="bold">incr</emph> (limiting to only integer values, for example).</para>
<para>For a more concrete illustration of the proposal, see the reference implementation, SF patch #1413115 [<url ref="http://sourceforge.net/tracker/index.php?func=detail&amp;aid=1413115&amp;group_id=10894&amp;atid=310894"/>].</para>
</section>
<section title="Discussion">
<para>There have been comments that <emph style="bold">incr</emph> modified as proposed would lose one means of typo-detection: If the varname is mistyped, then instead of throwing an error, it would turn into a noop.</para>
<para>My (TIP-originator) answer to this: relying on thrown exceptions for mistyped varnames is a very weak strategy in dynamic (non-compiled) languages like tcl, anyway, because it would require a 100%-test-coverage of execution-paths.</para>
<para>Nevertheless, this shouldn&apos;t exclude discussion about less typo-forgiving alternatives:</para>
<para>Proposed (by others) alternative #1: make <emph style="bold">incr</emph> accept a second optional argument <emph style="italic">init</emph> which, if specified, will cause <emph style="bold">incr</emph> to accept non-existent variables and initialize them with the value <emph style="italic">init</emph>. One disadvantage of this behaviour is, that it is at odds with append and lappend behaviour, which would rather imply that if more than one argument is given after the varname, then each of them would be added in row. Another con would be, that it would not be intuitive, whether the resulting value would be <emph style="italic">init</emph> or (<emph style="italic">init</emph> + <emph style="italic">increment</emph>). Similar alternatives mentioning new option <emph style="bold">-initValue</emph> are over-verbose imho.</para>
<para>Another way to partially reduce this proposal&apos;s forgiveness would be to allow autoinitialization only for array-elements. This looks grossly unorthogonal at first sight, but addresses the fact, that the primary reason for TIP 215 was counting occurrences of strings, which are then made keys in an array. The danger of mistyped array-keys is surely much lower than that of mistyped variable names. See <tipref type="text" tip="224"/></para>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
</section>
</body></TIP>

