Version 3 of lmap

Updated 2005-04-04 06:42:49 by antirez

Richard Suchenwirth 2005-04-02 - lmap is a "collecting foreach" which returns a list of its results. In Jim it is built in, but it can be easily had in pure Tcl:

 proc lmap {_var list body} {
    upvar 1 $_var var
    set res {}
    foreach var $list {lappend res [uplevel 1 $body]}
    set res
 }

Several usage examples are at Multiplication tables. Lmap is a compromise between Tcl and the classical functional programming function map, in that it takes a "quasi-lambda" which is split up into the _var name and the body arguments. However, this style is well-known from foreach, and somehow reads better:

 lmap i {1 2 3 4 5} {expr $i*$i}

vs.

 map [lambda i {expr $i*$i}] {1 2 3 4 5}

Jim's lmap uses continue to skip the accumulation of the current iteration, so it works like map and filter at the same time. In Jim lmap supports multiple lists in input like the real foreach, so you can do interesting things like this:

 . lmap a {1 2 3} b {A B C} {list $a $b}
 {1 A} {2 B} {3 C}

Multiple lists + accumulation + continue to skip makes it also somewhat similar to list comprehension (but simpler to use in the my (SS) opinion).


A cute variation is fmap (influenced by ApplyAll in Backus' FP; Joy has a comparable operator in cleave) which maps a list of functions on one argument:

 proc fmap {functions x}  {lmap f $functions {$f $x}}

Then we can write a file reader like this:

 proc << filename  {lindex [fmap {read close} [open $filename]] 0}

Category Functional Programming