<?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 12:01:34 GMT 2012 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='187'>
<header><title>Procedures as Values</title><author address="mailto:antirez@invece.org">Salvatore Sanfilippo</author><author address="mailto:msofer@users.sf.net">Miguel Sofer</author><author address="mailto:webscool@ihug.co.nz">Paul Nash</author><status type='project' state='rejected' tclversion="8.6" vote='after'>$Revision: 1.14 $</status><history></history><created day='20' month='apr' year='2004' /><keyword>Tcl lambda anonymous command function</keyword></header>
<abstract>This TIP describes a change in the semantics of Tcl to allow procedures to be first class values, being represented as strings, and in particular as three element lists.</abstract>
<body><section title="Rationale">
<para>The Tcl programming language is an homoiconic-form language. Program and data are both presented as strings. A Tcl procedure&apos;s arguments list and body are not an exception to this rule, but the procedure itself is handled as a name bound to a particular couple of arguments list and body. This name lives in a separated namespace and does not collide with variables names.</para>
<para>The first argument of every Tcl command should be the name of a built-in command, or a procedure (actually a procedure is a user defined command). In the latter case, the Tcl interpreter performs a lookup in a virtual table (that is indirectly accessible using <emph style="bold">proc</emph> and <emph style="bold">info</emph> commands), in order to check if there is a procedure with the specified name, and to call the procedure using the associated arguments list and body. If a procedure with the specified name is not present (nor a built-in command), the interpreter calls a special procedure named unknown to handle the exception, or raises an error if the unknown procedure does not exists.</para>
<para>This TIP proposes to modify the Tcl semantic in order to check if the command name is a valid, three-elements Tcl list with the first element of the list being the string <emph style="bold">lambda</emph>, before to lookup any built-in command or procedure. In such a case Tcl will call the procedure that is represented by the arguments list and body that are the second and third elements of the list. Procedures represented as three-elements lists are called <emph style="italic">anonymous procedures</emph> in this TIP, and are first class values as any other Tcl list.</para>
<para>The storage of an anonymous procedure is handled like any other Tcl object. Memory management is one of the main problems of procedures created &quot;on the fly&quot; in Tcl, so that to create anonymous procedures in Tcl in order to emulate the lambda operator, was and is a problem. With this TIP, anonymous procedures can be created just using the list command. The following is an example:</para>
<verbatim><vline encoding='base64'>ICAgICAgICBzZXQgcCBbbGlzdCBsYW1iZGEgeCB7c3RyaW5nIGxlbmd0aCAkeH1d</vline><vline encoding='base64'>ICAgICAgICAkcCBmb28=</vline></verbatim>
<para>The above script evaluates to 3. Fast, reliable anonymous procedures may allow Tcl to better support a functional approach that is very interesting to use in a language where the list is the main data structure.</para>
<subsection title="Examples">
<para>The following Tcl scripts (based on the classic list combinators from functional programming languages) should look very natural to most experienced Tcl programmers:</para>
<subsubsection title="Example 1: Use of Anonymous Commands with a [map] Command">
<verbatim><vline encoding='base64'>ICAgIHByb2MgbWFwIHtsaXN0IHByb2N9IHs=</vline><vline encoding='base64'>ICAgICAgICBzZXQgcmVzIHt9</vline><vline encoding='base64'>ICAgICAgICBmb3JlYWNoIGUgJGxpc3Qgew==</vline><vline encoding='base64'>ICAgICAgICAgICAgbGFwcGVuZCByZXMgWyRwcm9jICRlXQ==</vline><vline encoding='base64'>ICAgICAgICB9</vline><vline encoding='base64'>ICAgICAgICByZXR1cm4gJHJlcw==</vline><vline encoding='base64'>ICAgIH0=</vline><vline encoding='base64'></vline><vline encoding='base64'>ICAgIHNldCBhIFtsaXN0IG9uZSB0d28gdGhyZWUgZm91ciBmaXZlXQ==</vline><vline encoding='base64'>ICAgIHNldCBiIFttYXAgJGEgW2xpc3QgbGFtYmRhIHgge3N0cmluZyBsZW5ndGggJHh9XV0=</vline></verbatim>
<para>This evaluates to [list 3 3 5 4 4]</para>
</subsubsection>
<subsubsection title="Example 2: Use of Anonymous Commands with a [filter] Command">
<verbatim><vline encoding='base64'>ICAgIHByb2MgZmlsdGVyIHtsaXN0IHByb2N9IHs=</vline><vline encoding='base64'>ICAgICAgICBzZXQgcmVzIHt9</vline><vline encoding='base64'>ICAgICAgICBmb3JlYWNoIGUgJGxpc3Qgew==</vline><vline encoding='base64'>ICAgICAgICAgICAgaWYgeyFbJHByb2MgJGVdfSB7</vline><vline encoding='base64'>ICAgICAgICAgICAgICAgIGxhcHBlbmQgcmVzICRl</vline><vline encoding='base64'>ICAgICAgICAgICAgfQ==</vline><vline encoding='base64'>ICAgICAgICB9</vline><vline encoding='base64'>ICAgICAgICByZXR1cm4gJHJlcw==</vline><vline encoding='base64'>ICAgIH0=</vline><vline encoding='base64'></vline><vline encoding='base64'>ICAgIHNldCBhIFtsaXN0IDEgMTAgMTAwIDQgNV0=</vline><vline encoding='base64'>ICAgIHNldCBiIFtmaWx0ZXIgJGEgW2xpc3QgbGFtYmRhIHgge2V4cHIgJHg8MTB9XV0=</vline></verbatim>
<para>This evaluates to [list 10 100]</para>
<para>Note: In practice, defining an alias, <emph style="bold">lambda</emph>, for <emph style="bold">list lambda</emph> leads to more natural-looking code.</para>
<para>&lt;PN&gt; </para>
<verbatim><vline encoding='base64'>ICAgIChiaW4pIDIwICUgbGlzdCBsYW1iZGEgeCB7c3RyaW5nIGxlbmd0aCAkeH0=</vline><vline encoding='base64'>ICAgIGxhbWJkYSB4IHtzdHJpbmcgbGVuZ3RoICR4fQ==</vline><vline encoding='base64'>ICAgIChiaW4pIDIxICUgbGFtYmRhIHgge3N0cmluZyBsZW5ndGggJHh9</vline><vline encoding='base64'>ICAgIGxhbWJkYSB4IHtzdHJpbmcgbGVuZ3RoICR4fQ==</vline><vline encoding='base64'>ICAgIChiaW4pIDIyICUg</vline></verbatim>
<para>No alias is required &lt;/PN&gt;</para>
<para>The author of this TIP thinks that many Tcl programmers will enjoy the ability to use this programming style. The Tcl folklore actually implemented different versions of <emph style="bold">lambda</emph> in the past, but no one is suitable for prime time.</para>
<para>Still, the ability to manipulate lists in a simpler way can make Tcl more enjoyable.</para>
<para>The new semantic introduced by this TIP is not only needed to use operators like <emph style="italic">map</emph> and <emph style="italic">filter</emph>, but generally makes Tcl able to address high-order programming in a clean way: procedures that returns procedures, Currying, and functional composition are all possible using the TIP&apos;s first class procedures in a straightforward way.</para>
<para>There are probably other interesting applications in the field of the Object Oriented Programming.</para>
</subsubsection>
</subsection>
</section>
<section title="Proposed Change">
<para>The proposed change is to check if the first argument of a command is an anonymous procedure before to perform any other lookup. This test should be fast using the object&apos;s string representation because a Tcl list having as first argument the string &quot;lambda&quot; must start in a proper way that is easy to detect.</para>
<para>The procedure can be byte-compiled when it&apos;s called the first time, the byte-compiled version can be referenced from the internal representation of the <emph style="italic">Tcl_Obj</emph> representing the procedure. The original string representation of the anonymous procedure can be cached inside the <emph style="italic">Tcl_Obj</emph> in order to be able to recreate it when needed as for <emph style="italic">Tcl_Obj</emph> semantic.</para>
<para>Actually the implementation may create a conventional Tcl procedure associated and referenced by the anonymous procedure&apos;s object, that can be released when the internal representation of the anonymous procedure&apos;s <emph style="italic">Tcl_Obj</emph> is freed.</para>
<para>The real Tcl procedure may live in the <emph style="bold">::lambda</emph> namespace in order to be self-introspective.</para>
</section>
<section title="Reference Implementation">
<para>A reference implementation is being developed in Patch #940207 (superseeding the previous #939190) [<url ref="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=940207&amp;group_id=10894&amp;atid=310894"/>]</para>
<para>It follows this tip fairly closely in its effects, but diverges in the implementation strategy. It implements autocleaning procs, and defines lambda expressions as autocleaning procs in (for instance) the ::tcl::lambda namespace. The example above can be defined equivalently as</para>
<verbatim><vline encoding='base64'>ICAgc2V0IHAgW2xhbWJkYSB4IHtzdHJpbmcgbGVuZ3RoICR4fV0=</vline><vline encoding='base64'>ICAgc2V0IHAgW2xpc3QgOjp0Y2w6OmxhbWJkYTo6IHgge3N0cmluZyBsZW5ndGggJHh9XQ==</vline><vline encoding='base64'>ICAgc2V0IHAgezo6dGNsOjpsYW1iZGE6OiB4IHtzdHJpbmcgbGVuZ3RoICR4fX0=</vline></verbatim>
<para>although the last version will prevent autocleanup (due to the name being stored in a shared literal).</para>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
</section>
</body></TIP>

