[Richard Suchenwirth] 2002-11-30 - Lambdas are anonymous functions - "procs with no name" (see [Lambda in Tcl]), or put the other way, functions are just named lambdas. A few ways of bringing Lambdas to Tcl have been proposed, which were most concerned with picking a name, and then defining a [proc]. This however leads to a garbage collection problem, as such procs live in the global namespace and are never cleared up. Here I try a different approach - let lambdas be just strings ([everything is a string]) that can be parsed as a list of two elements - the argument list and the body. For instance, here's a squarer: {x} {expr $x*$x} One may assign such values to a variable (or array element), or pass them around by value: set sq {{x} {expr $x*$x}} To "run" a lambda, to make it execute like a Tcl command, the first take is an explicit ''apply'':} proc apply {lambda args} { foreach {argl body} $lambda break if {[llength $argl] != [llength $args]} { error "argument mismatch, expected $argl" } foreach $argl $args break if 1 $body } if 0 { % set sq {x {expr {$x*$x}}} x {expr {$x*$x}} % apply $sq 5 25 But to prefix each lambda invocation with ''apply'' seems like back in the dark (Fortran CALL, Basic GOSUB) ages... So let's see how to get Tcl to call ''apply'' automatically when meeting a lambda. Lambdas are lists of two elements, so if we assert that "normal" command names do not contain exactly one space, we can extend [unknown] to ''apply'' commands whose name happens to be alist of length 2: } proc unknown args [string map [list @ [info body unknown]] { if {[llength [lindex $args 0]]==2} { return [uplevel 1 apply $args] } @}] if 0 {Now we can call our lambdas by given name: % $sq 5 25 or, if we don't bother picking a name, by explicit specification: % {x {expr sqrt($x)}} 25 5.0 The drawback is that the lambda body goes through [eval] every time, so is slower than a byte-compiled [proc] body. On the other hand, we don't have to worry about garbage, as local variables are disposed of automatically - and we finally have real [local procedures]... } ---- [[ [Category Data Structure] | ]]