Version 4 of apply

Updated 2006-03-29 15:12:33 by suchenwi

What: apply

 Where: http://www.glinx.com/%7Ehclsmith/plugin.html  ???
 Description: Version of the apply procedure as discussed on
        <URL: news:comp.lang.tcl > during February, 1997.
        Versions of Tcl C and scripting routines as well as a
        lisp-backquote-like proc are available.  Now supports Tcl 8.x.
 Updated: 09/1999
 Contact: mailto:[email protected] (Hume Smith)

apply will be a command in 8.5 - see TIP 194 [L1 ] which also gives an illustrative implementation in pure-Tcl.

 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
 }

RS wonders, however, how the following simpler take is insufficient:

 proc apply {fun args} {
   foreach {argl body ns} $fun break
   namespace eval $ns [list foreach $argl $args break]
   namespace eval $ns $body
 }

Testing:

 % apply {x {expr $x*$x}} 5
 25
 % apply {{x y} {expr hypot($x,$y)} foo} 3 4
 5.0

NEM The difference is that in your version parameters are persistent namespace variables, rather than local to the procedure. Consider:

 % interp alias {} test1 {} apply {x { expr {$x * $x} }}
 test1
 % interp alias {} test2 {} apply {x { set y [test1 12]; return $x }}
 test2
 % test2 "Hello!"
 12

Which isn't what you want, I expect. - RS: Indeed. In fact, I didn't want namespaces at all :) - just because the other version had them... I started with

 proc apply {fun args} {
   foreach {argl body ns} $fun break
   namespace eval $ns [list foreach $argl $args break]
   namespace eval $ns $body
 }

Category Package - Category Command