[SS]: This is a Pure TCL implementation of TIP187. Note that the semantic is the same, including the fact that [lambda] will never leak. The only difference with the TIP is the "prcedence" of lambda. In this implementation the order is: command lookup, lambda lookup, unknonw call. This should not make any difference. # Pure Tcl implementation of TIP 187 (Procedures as Values) # Copyright(C) 2004 Salvatore Sanfilippo # Under the Same license as Tcl8.4 namespace eval tip187 {set counter 0} rename unknown tip187_orig_unknown proc unknown args { set func [lindex $args 0] set funcargs [lrange $args 1 end] if {[llength $func] == 3 && [lindex $func 0] eq {lambda}} { set c [incr ::tip187::counter] set t [list proc ::tip187::lambda$c [lindex $func 1] [lindex $func 2]] if {![catch {uplevel $t}]} { set retval [uplevel ::tip187::lambda$c $funcargs] rename ::tip187::lambda$c {} return $retval } catch {rename ::tip187::lambda$c {}} } else { uplevel tip187_orig_unknown $args } } proc lambda {arglist body} { list lambda $arglist $body } ### Variadic MAP version proc map {func args} { if {[llength $args] > 1} { for {set j 1} {$j < [llength $args]} {incr j} { if {[llength [lindex $args $j]] != [llength [lindex $args 0]]} { error "Lists of different length as input for \[map\]" } } } set result {} for {set i 0} {$i < [llength [lindex $args 0]]} {incr i} { set callargs {} for {set j 0} {$j < [llength $args]} {incr j} { lappend callargs [lindex [lindex $args $j] $i] } lappend result [eval [list $func] $callargs] } return $result } ### Examples ### set l1 {1 2 3 4 5} set l2 {10 20 30 40 50} set l3 [map [lambda {x y} {expr $x+$y}] $l1 $l2] puts $l3 [EB]: These examples fails: % map [list string length] {az bn dfg} invalid command name "string length" % lsort -command [lambda {x y} {expr {$x < $y}}] {2 4 1} wrong # args: should be "lambda arglist body" [[map]] must be used with with a command or a lambda, not a command prefix, and lambda must be list-quoted. Sounds counter-intuitive to me. % lsort -command [list [lambda {x y} {expr {$x < $y}}]] {2 4 1} 4 2 1 [SS]: It must be list quoted for a [lsort] specific issue, actually the option does not do what the name is suggesting (i.e. using the -command option as a command), but is using [eval]. You can't even use a standard procedure if its name contains spaces in the same condition. This lambas works in any place where a command is expected, If instead a "token" is expected it must be list-quoted. About your first example, it's not correct. The correct version is: map [list lambda x {string length $x}] {az bn dgf} ; # => {2 2 3} But you can kill "list" if you want and just write map [lambda x {strnig length $x}] {az bn dgf} [DKF]: Actually [lsort]'s guts are even nastier than that. It does something grotty because like that it can at least be a bit faster, and that makes a huge difference for a sorting engine. Oh, and if you make the first word of the list returned by [[lambda]] be itself a command, you can make the lambda engine much more robust against such sloppy use.