Version 12 of lambda in tcl8.5

Updated 2009-12-29 16:40:53 by pmarin

As of tcl8.5, Tcl has native support for lambda, provided by means of apply per TIP 194 [L1 ].

The apply command is documented here http://www.tcl.tk/man/tcl8.5/TclCmd/apply.htm

This enables the following:

   proc lambda {arglist body {ns {}}} {
     list ::apply [list $arglist $body $ns]
   }

An example of its use:

   set q [lambda {x} {incr x}]
   {*}$q 1
   % 2

The significant thing here is that (in the above example) $q will contain an anonymous proc which will byte compile itself. So subsequent invocations of {*}$q will not incur a recompilation. The anonymous proc will persist as long as it's not shimmered away, and can be passed around as a value!

This is ubercool - guilt-free lambda.

NEM notes also that in many places where lambdas are useful, the explicit {*} is not necessary -- e.g. most commands which accept callbacks will automatically expand the command anyway:

 % lsort -command [lambda {x y} {
     expr {[string length $x] < [string length $y]}
   }] "My name is Neil"
 name Neil My is
 % trace add variable ::foo write [lambda args {
     puts "foo = $::foo"
 }]
 % set foo 12
 foo = 12
 12

pmarin. Scheme like define:

 proc def { _name arglist body {ns {}} } { 
    upvar $_name name        
    set name [list ::apply [list $arglist $body $ns]]
 }

 def q {x} {incr x}
 >{*}$q 1
 2

With this unknown function is possible to call an anonymous proc like a normal proc (without "{*}$" )

 rename unknown _original_unknown
 proc unknown args {
    set _name [lindex $args 0]        
    upvar $_name name
    if { ![catch {set name }]} {
       if { [lindex $name 0] == "::apply"} {
          return [uplevel 1 [list {*}$name {*}[lrange $args 1 end]]]
       } 
    }
    uplevel 1 [list _original_unknown {*}$args]
 }

 def q {} {incr x}
 >q 1
 2

[ Category Example ]