User:Ushkin N/Comparison of programming languages/Functional/Map
The map function originated in functional programming languages.
The Lisp programming language introduced a map function called maplist
[1] in 1959, with slightly different versions already appearing in 1958.[2] This is the original definition for maplist
, mapping a function over successive rest lists:
maplist[x;f] = [null[x] -> NIL;T -> cons[f[x];maplist[cdr[x];f]]]
The function maplist
is still available in newer Lisps like Common Lisp,[3] though functions like mapcar</co de> or the more generic
map
would be preferred.
Squaring the elements of a list using
maplist
would be written in s-expression notation like this:
(maplist (function (lambda (l)
(sqr (car l))))
'(1 2 3 4 5))
Using the function mapcar
, above example would be written like this:
(mapcar (function sqr) '(1 2 3 4 5))
Today mapping functions are supported (or may be defined) in many procedural, object oriented, and multi-paradigm languages as well: In C++'s Standard Template Library, it is called std::transform
, in C# (3.0)'s LINQ library, it is provided as an extension method called Select
. Map is also a frequently used operation in high level languages such as CFML, Perl, Python and Ruby; the operation is called map
in all four of these languages. A collect
alias for map
is also provided in Ruby (from Smalltalk). Common Lisp provides a family of map-like functions; the one corresponding to the behavior described here is called mapcar
(-car
indicating access using the CAR operation). There are also languages with syntactic constructs providing the same functionality as the map function.
Map is sometimes generalized to accept dyadic (2-argument) functions that can apply a user-supplied function to corresponding elements from two lists; some languages use special names for this, such as map2 or zipWith. Languages using explicit variadic functions may have versions of map with variable arity to support variable-arity functions. Map with 2 or more lists encounters the issue of handling when the lists are of different lengths. Various languages differ on this; some raise an exception, some stop after the length of the shortest list and ignore extra items on the other lists; some continue on to the length of the longest list, and for the lists that have already ended, pass some placeholder value to the function indicating no value.
In languages which support first-class functions, map
may be partially applied to lift a function that only works on a single value to an element-wise equivalent that works on an entire container; for instance, map square
is a Haskell function which squares each element of a list.
Map in various languages
Language
Map
Map 2 lists
Map n lists
Notes
Handling lists of different lengths
Common Lisp
(mapcar func list)
(mapcar func list1 list2)
(mapcar func list1 list2 ...)
stops after the length of the shortest list
C++
std::transform(begin, end, result, func)
std::transform(begin1, end1, begin2, result, func)
in header <algorithm>
begin, end, and result are iterators
result is written starting at result
C#
ienum.Select(func)
or
The select
clause
ienum1.Zip(ienum2, func)
Select
is an extension method
ienum is an IEnumerable
Zip
is introduced in .NET 4.0
Similarly in all .NET languages
stops after the shortest list ends
CFML
obj.map(func)
Where obj
is an array or a structure. func
receives as arguments each item's value, its index or key, and a reference to the original object.
Clojure
(map func list)
(map func list1 list2)
(map func list1 list2 ...)
stops after the shortest list ends
D
list.map!func
zip(list1, list2).map!func
zip(list1, list2, ...).map!func
Specified to zip by StoppingPolicy: shortest, longest, or requireSameLength
Erlang
lists:map(Fun, List)
lists:zipwith(Fun, List1, List2)
zipwith3
also available
Lists must be equal length
Elixir
Enum.map(list, fun)
Enum.zip(list1, list2) |> Enum.map(fun)
List.zip([list1, list2, ...]) |> Enum.map(fun)
stops after the shortest list ends
F#
List.map func list
List.map2 func list1 list2
Functions exist for other types (Seq and Array)
Throws exception
Haskell
map func list
zipWith func list1 list2
zipWithn func list1 list2 ...
n
corresponds to the number of lists; predefined up to zipWith7
stops after the shortest list ends
Groovy
list.collect(func)
[list1 list2].transpose().collect(func)
[list1 list2 ...].transpose().collect(func)
Haxe
array.map(func)
list.map(func)
Lambda.map(iterable, func)
J
func list
list1 func list2
func/ list1, list2, list3 ,: list4
J's array processing capabilities make operations like map implicit
length error if list lengths not equal
Java 8+
stream.map(func)
JavaScript 1.6
ECMAScript 5
array#map(func)
List1.map(function (elem1, i) {
return func(elem1, List2[i]); })
List1.map(function (elem1, i) {
return func(elem1, List2[i], List3[i], ...); })
Array#map passes 3 arguments to func: the element, the index of the element, and the array. Unused arguments can be omitted.
Stops at the end of List1, extending the shorter arrays with undefined items if needed.
Logtalk
map(Closure, List)
map(Closure, List1, List2)
map(Closure, List1, List2, List3, ...) (up to seven lists)
Only the Closure argument must be instantiated.
Failure
Mathematica
func /@ list
Map[func, list]
MapThread[func, {list1, list2}]
MapThread[func, {list1, list2, ...}]
Lists must be same length
Maxima
map(f, expr1, ..., exprn)
maplist(f, expr1, ..., exprn)
map returns an expression whose leading operator is the same as that of the expressions;
maplist returns a list
OCaml
List.map func list
Array.map func array
List.map2 func list1 list2
raises Invalid_argument exception
PARI/GP
apply(func, list)
—
Perl
map block list
map expr, list
In block or expr special variable $_ holds each value from list in turn.
Helper List::MoreUtils::each_array
combines more than one list until the longest one is exhausted, filling the others with undef.
PHP
array_map(callable, array)
array_map(callable, array1,array2)
array_map(callable, array1,array2, ...)
The number of parameters for callable
should match the number of arrays.
extends the shorter lists with NULL items
Prolog
maplist(Cont, List1, List2).
maplist(Cont, List1, List2, List3).
maplist(Cont, List1, ...).
List arguments are input, output or both. Subsumes also zipWith, unzip, all
Silent failure (not an error)
Python
map(func, list)
map(func, list1, list2)
map(func, list1, list2, ...)
Returns a list in Python 2 and an iterator in Python 3.
zip()
and map()
(3.x) stops after the shortest list ends, whereas map()
(2.x) and itertools.zip_longest()
(3.x) extends the shorter lists with None
items
Ruby
enum.collect {block}
enum.map {block}
enum1.zip(enum2).map {block}
enum1.zip(enum2, ...).map {block}
[enum1, enum2, ...].transpose.map {block}
enum is an Enumeration
stops at the end of the object it is called on (the first list); if any other list is shorter, it is extended with nil items
S/R
lapply(list, func)
mapply(func, list1, list2)
mapply(func, list1, list2, ...)
Shorter lists are cycled
Scala
list.map(func)
(list1, list2).zipped.map(func)
(list1, list2, list3).zipped.map(func)
note: more than 3 not possible.
stops after the shorter list ends
Scheme, Racket
(map func list)
(map func list1 list2)
(map func list1 list2 ...)
lists must all have same length
Smalltalk
aCollection collect: aBlock
aCollection1 with: aCollection2 collect: aBlock
Fails
Standard ML
map func list
ListPair.map func (list1, list2)
ListPair.mapEq func (list1, list2)
For 2-argument map, func takes its arguments in a tuple
ListPair.map
stops after the shortest list ends, whereas ListPair.mapEq
raises UnequalLengths
exception
Swift
array.map(func)
map(sequence, func)
map(zip(sequence1, sequence2), func)
stops after the shortest list ends
XPath 3
XQuery 3
list ! block
for-each(list, func)
for-each-pair(list1, list2, func)
In block
the context item .
holds the current value
stops after the shortest list ends
References