<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://www.tcl.tk/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Wed Jun 19 23:21:36 GMT 2013 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='284'>
<header><title>New &apos;invoke&apos; and &apos;namespace invoke&apos; Commands</title><author address="mailto:msofer@users.sourceforge.net">Miguel Sofer</author><status type='project' state='draft' tclversion="8.7" vote='prior'>$Revision: 1.23 $</status><history></history><created day='1' month='oct' year='2006' /></header>
<abstract>This TIP exposes a Tcl script-level interface to the direct command invokation engine already present in the Tcl library for years.</abstract>
<body><section title="Proposed New Commands">
<para>This TIP proposes a new subcommand to <emph style="bold">namespace</emph>, <emph style="bold">invoke</emph>, with the following syntax:</para>
<quote><emph style="bold">namespace invoke</emph> <emph style="italic">namespace</emph> <emph style="italic">cmd</emph> ?<emph style="italic">arg</emph> ...?</quote>
<para>This invokes the command called <emph style="bold">cmd</emph> in the caller&apos;s scope, as resolved from namespace <emph style="italic">namespace</emph>, with the supplied arguments. If <emph style="italic">namespace</emph> does not exist, the command returns an error.</para>
<para>This TIP also proposes a new command:</para>
<quote><emph style="bold">invoke</emph> <emph style="italic">level</emph> <emph style="italic">cmd</emph> ?<emph style="italic">arg</emph> ...?</quote>
<para>This invokes the command <emph style="italic">cmd</emph> in level <emph style="italic">level</emph> with the supplied <emph style="italic">arg</emph>uments. The syntax of <emph style="italic">level</emph> is the same as that required by <emph style="bold">uplevel</emph>.</para>
</section>
<section title="Rationale">
<para>There is currently no script-level equivalent to <emph style="italic">Tcl_EvalObjv()</emph>, though the functionality is provided by one of:</para>
<verbatim><vline encoding='base64'>ICAgZXZhbCBbbGlzdCBjbWQgP2FyZyAuLi4/XQ==</vline><vline encoding='base64'>ICAgeyp9W2xpc3QgY21kID9hcmcgLi4uP10=</vline></verbatim>
<para>Note that the core tries to optimise the first case, but has to be careful to only avoid reparsing when it is guaranteed safe to do so. The notation is rather clumsy too.</para>
<para>The proposed new commands try to improve this situation, with the added functionality of determining the namespace in which the command name is to be resolved (functionality which was very difficult to use previously using the script-level API). In this manner it is possible for the invocation to make good use of <emph style="bold">namespace path</emph> and <emph style="bold">namespace unknown</emph> features.</para>
<para>The new command <emph style="bold">invoke</emph> could be implemented as:</para>
<verbatim><vline encoding='base64'>ICAgcHJvYyBpbnZva2Uge2xldmVsIGFyZ3N9IHs=</vline><vline encoding='base64'>ICAgICAgIGlmIHtbbGxlbmd0aCAkYXJnc10gPT0gMH0gew==</vline><vline encoding='base64'>ICAgICAgICAgICByZXR1cm4gLWNvZGUgZXJyb3IgU29tZU1lc3NhZ2U=</vline><vline encoding='base64'>ICAgICAgIH0=</vline><vline encoding='base64'>ICAgICAgIGlmIHtbc3RyaW5nIGlzIGludGVnZXIgJGxldmVsXSAmJiAoJGxldmVsID49IDApfSB7</vline><vline encoding='base64'>ICAgICAgICAgICBpbmNyIGxldmVs</vline><vline encoding='base64'>ICAgICAgIH0=</vline><vline encoding='base64'>ICAgICAgIHVwbGV2ZWwgJGxldmVsICRhcmdz</vline><vline encoding='base64'>ICAgfV0=</vline></verbatim>
</section>
<section title="Reference Implementation and Documentation">
<para>[RFE 1577324] (which depends on [Patch 1577278]) provides an implementation of <emph style="bold">namespace invoke</emph>. [<url ref="https://sourceforge.net/support/tracker.php?aid=1577324"/>] [<url ref="https://sourceforge.net/support/tracker.php?aid=1577278"/>]</para>
</section>
<section title="Differences to Other Commands">
<enumerate><item.e index='1'><para>Both these commands perform command invocation, as opposed to the script evaluation done by <emph style="bold">eval</emph>, <emph style="bold">uplevel</emph>, <emph style="bold">namespace eval</emph> and <emph style="bold">namespace inscope</emph></para></item.e><item.e index='2'><para><emph style="bold">namespace inscope</emph> does a magic expansion of the first argument, <emph style="bold">namespace invoke</emph> takes the first argument as a command name. In other words, <emph style="bold">namespace inscope</emph> can be used with a command prefix. <emph style="italic">Feedback on the semantics suggest that this is a worthy feature, very useful for packing up command prefixes. This tip may yet be revised or withdrawn to take that into consideration.</emph></para></item.e><item.e index='3'><para>Both <emph style="bold">namespace eval</emph> and <emph style="bold">namespace inscope</emph> add a call frame,<emph style="bold">namespace invoke</emph> does not - it invokes in the caller&apos;s frame.</para></item.e></enumerate>
</section>
<section title="Sample Usage">
<para>In tcllib&apos;s <emph style="bold">::math::calculus::romberg</emph> we see (edited for brevity):</para>
<verbatim><vline encoding='base64'>ICAgICMgUmVwbGFjZSBmIHdpdGggYSBjb250ZXh0LWluZGVwZW5kZW50IHZlcnNpb24=</vline><vline encoding='base64'></vline><vline encoding='base64'>ICAgIHNldCBmcW5hbWUgW3VwbGV2ZWwgMSBbbGlzdCBuYW1lc3BhY2Ugd2hpY2ggW2xpbmRleCAkZiAwXV1d</vline><vline encoding='base64'>ICAgIHNldCBmIFtscmVwbGFjZSAkZiAwIDAgJGZxbmFtZV0=</vline><vline encoding='base64'>ICAgIC4uLg==</vline><vline encoding='base64'>ICAgIHNldCBjbWQgJGY=</vline><vline encoding='base64'>ICAgIGxhcHBlbmQgY21kIFtleHByIHswLjUgKiAoJGEgKyAkYil9XQ==</vline><vline encoding='base64'>ICAgIHNldCB2IFtldmFsICRjbWRd</vline></verbatim>
<para>where the command name in the prefix <emph style="italic">f</emph> is replaced with its fully qualified name. A further variable is lappended, and the result is sent to <emph style="bold">eval</emph>.</para>
<para>With <emph style="bold">namespace invoke</emph> and <emph style="bold">invoke</emph> this would be coded as:</para>
<verbatim><vline encoding='base64'>ICAgIHNldCBucyBbaW52b2tlIDEgbmFtZXNwYWNlIGN1cnJlbnRd</vline><vline encoding='base64'>ICAgIHNldCBmIFtsaXN0IG5hbWVzcGFjZSBpbnZva2UgJG5zIHsqfSRmXQ==</vline><vline encoding='base64'>ICAgIC4uLg==</vline><vline encoding='base64'>ICAgIHNldCB2IFt7Kn0kZiBbZXhwciB7MC41ICogKCRhICsgJGIpfV1d</vline></verbatim>
<para>If both new commands took the <emph style="italic">cmd</emph> argument as a prefix to be expanded (as suggested by some early commenters), it would be even nicer for this usage:</para>
<verbatim><vline encoding='base64'>ICAgIHNldCBucyBbaW52b2tlIDEgW2xpc3QgbmFtZXNwYWNlIGN1cnJlbnRdXQ==</vline><vline encoding='base64'>ICAgIHNldCBmIFtsaXN0IG5hbWVzcGFjZSBpbnZva2UgJG5zICRmXQ==</vline><vline encoding='base64'>ICAgIC4uLg==</vline><vline encoding='base64'>ICAgIHNldCB2IFtpbnZva2UgMCAkZiBbZXhwciB7MC41ICogKCRhICsgJGIpfV1d</vline></verbatim>
<para>The same thing (with slightly different semantics and a performance cost due to script evaluation instead of command invocation) could be obtained today by doing:</para>
<verbatim><vline encoding='base64'>ICAgIHNldCBmIFt1cGxldmVsIDEgW2xpc3QgbmFtZXNwYWNlIGNvZGUgW2xpc3QgdXBsZXZlbCAxICRmXV1d</vline><vline encoding='base64'>ICAgIC4uLg==</vline><vline encoding='base64'>ICAgIHNldCB2IFtldmFsIFtsYXBwZW5kIGYgW2V4cHIgezAuNSAqICgkYSArICRiKX1dXV0=</vline></verbatim>
<para>In order to fully reproduce the semantics and performance it would have to be:</para>
<verbatim><vline encoding='base64'>ICAgIHNldCBmIFt1cGxldmVsIDEgW2xpc3QgbmFtZXNwYWNlIGNvZGUgW2xpc3QgdXBsZXZlbCAxICRmXV1d</vline><vline encoding='base64'>ICAgIC4uLg==</vline><vline encoding='base64'>ICAgIGxzZXQgZiBlbmQgZW5kIFtsaW5zZXJ0IFtsaW5kZXggJGYgZW5kIGVuZF0gZW5kIFtleHByIHswLjUgKiAoJGEgKyAkYil9XV0gIA==</vline><vline encoding='base64'>ICAgIHNldCB2IFtldmFsICRmXQ==</vline></verbatim>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
</section>
</body></TIP>
