# TIP 194: Procedures as Values via '''apply'''
	Author:         Miguel Sofer <msofer@users.sf.net>
	Author:         Joe Mistachkin <joe@mistachkin.com>
	State:          Final
	Type:           Project
	Vote:           Done
	Created:        30-Apr-2004
	Post-History:   
	Keywords:       Tcl,lambda,anonymous,command,function,functional programming
	Tcl-Version:    8.5
	Tcl-Ticket:     944803
-----

# Abstract

This TIP proposes a new command, tentatively named **apply**, to
allow procedures to be first class values.  It is an alternative to
the approach of [[187]](187.md), where attaining a similar goal requires a
syntactic and semantic change.

# Rationale

Tcl is typeless, and every first class value is a string \(or at least
representable as such\).  Strings are managed by reference counting in
the Tcl core, the required memory is freed automatically when the
string is no longer referenced.

Tcl commands may interpret their arguments differently. Some commands
interpret some of their arguments as scripts - **eval**,
**uplevel**, and so on.  But no current Tcl command is able to
specify that a script is to be run in an isolated environment, free of
unwanted side effects or memory leaks caused by name collisions.

In order to achieve this isolation, one has to define a new command
via **proc** and assume the burden of name-collision avoidance and
lifetime management, or else produce complicated scripts with ugly
contorsions to avoid the name collisions.

Both [[187]](187.md) and this one propose ways to provide this lacking
functionality to Tcl.  The approach here is to do so by creating a new
**apply** command without any change to Tcl's syntax.

# Specification

A reference manual page can be found at
<http://utdt.edu/~mig/apply2.html> . Summarizing, the syntax of the new
command is:

 * **apply** _func_ ?_arg1 arg2 ..._?

	 > The first argument _func_ is an anonymous function - a list of
   two or three elements [**list** _arglist body_
   ?_namespace_?]. The first two are exactly like the arguments to
   **proc**, the third determines the namespace for **variable**,
   **namespace** and command resolution when the body is
   evaluated. The _namespace_ is interpreted as fixed, and is the
   interpreter's global namespace in the two-argument case.

	 > The remaining arguments _arg1 arg2 ..._ are taken as values for
   the first formal arguments in _arglist_.

The semantics of **apply** \(with the exception of some of the fine
details of error messages\) can be described by:

	 proc apply {fun args} {
	     set len [llength $fun]
	     if {($len < 2) || ($len > 3)} {
	         error "can't interpret \"$fun\" as anonymous function"
	     }
	     lassign $fun argList body ns
	     set name ::$ns::[getGloballyUniqueName]
	     set body0 {
	         rename [lindex [info level 0] 0] {}
	     }
	     proc $name $argList ${body0}$body
	     set code [catch {uplevel 1 $name $args} res opt]
	     return -options $opt $res
	 }

where the availability of a **getGloballyUniqueName** procedure was
assumed.

# Reference Implementation

There is a patch
<http://sf.net/tracker/?func=detail&aid=944803&group_id=10894&atid=360894> 
that implements this TIP.

The patch defines a new _tclLambdaType_ for _Tcl\_Obj_s that caches
the internal structures necessary for efficient evaluation: a Proc
struct, a pointer to _namespace_, and the bytecodes implementing
_body_.  It is a small patch that relies heavily on the
implementation of **proc**, producing essentially a regular
**proc** with no command attached to it: an anonymous function.

All cached internal structures are freed when _func_ ceases to be
referenced or when it loses its internal representation as a
_tcllambdaType_ through shimmering.

Note that a similar approach is likely for a definitive implementation
of [[187]](187.md).

# Further Functional Programming Constructs

The availability of **apply** permits an easy and efficient access
to other FP functions. For example one might define a constructor
**lambda** and a **curry** command like this:

	 proc lambda {arglist body {ns {}}} {
	     list ::apply [list $arglist $body $ns]
	 }
	
	 proc curry {lam args} {
	     lappend lam {expand}$args
	 }

Function composition is also relatively easy to specify. Further
examples may be seen in the Wiki, see for instance Neil Madden's
**map**, **filter**, **foldl**, **foldr**
<http://wiki.tcl.tk/11141>  - note that the syntax is slightly
different from the one proposed here.

# Comparison to TIP 187 and outlook

In terms of usage, the main difference is that where TIP 187 does:

	 set p [list lambda x {string length $x}]
	 $p $foo

we would do here:

	 set p [list ::apply [list x {string length $x}]]
	 # or: set p [lambda x {string length $x}]
	 {expand}$p $foo ;# or 'eval $p [list $foo]', or ...

or else:

	 set p [list x {string length $x}]
	 apply $p $foo

This TIP requires no changes to the rules in Tcl\(n\), whereas [[187]](187.md)
requires a change in rule [[2]](2.md).

If in the future Tcl evolves a rule for automatic expansion of leading
words, **apply** will provide automatically the syntax of [[187]](187.md).

# Copyright

This document has been placed in the public domain.

