Map (higher-order function)
   HOME

TheInfoList



OR:

In many
programming language A programming language is a system of notation for writing computer programs. Most programming languages are text-based formal languages, but they may also be graphical. They are a kind of computer language. The description of a programming l ...
s, map is the name of a higher-order function that applies a given function to each element of a collection, e.g. a
list A ''list'' is any set of items in a row. List or lists may also refer to: People * List (surname) Organizations * List College, an undergraduate division of the Jewish Theological Seminary of America * SC Germania List, German rugby uni ...
or set, returning the results in a collection of the same type. It is often called ''apply-to-all'' when considered in
functional form In mathematics and computer science, a higher-order function (HOF) is a function that does at least one of the following: * takes one or more functions as arguments (i.e. a procedural parameter, which is a parameter of a procedure that is itsel ...
. The concept of a map is not limited to lists: it works for sequential containers, tree-like containers, or even abstract containers such as
futures and promises In computer science, future, promise, delay, and deferred refer to constructs used for synchronizing program execution in some concurrent programming languages. They describe an object that acts as a proxy for a result that is initially unknown ...
.


Examples: mapping a list

Suppose we have a list of integers
, 2, 3, 4, 5 The comma is a punctuation mark that appears in several variants in different languages. It has the same shape as an apostrophe or single closing quotation mark () in many typefaces, but it differs from them in being placed on the baseline o ...
/code> and would like to calculate the square of each integer. To do this, we first define a function to square a single number (shown here in Haskell): square x = x * x Afterwards we may call >>> map square
, 2, 3, 4, 5 The comma is a punctuation mark that appears in several variants in different languages. It has the same shape as an apostrophe or single closing quotation mark () in many typefaces, but it differs from them in being placed on the baseline o ...
which yields
, 4, 9, 16, 25 The comma is a punctuation mark that appears in several variants in different languages. It has the same shape as an apostrophe or single closing quotation mark () in many typefaces, but it differs from them in being placed on the baseline o ...
/code>, demonstrating that map has gone through the entire list and applied the function square to each element.


Visual example

Below, you can see a view of each step of the mapping process for a list of integers X =
, 5, 8, 3, 2, 1 The comma is a punctuation mark that appears in several variants in different languages. It has the same shape as an apostrophe or single closing quotation mark () in many typefaces, but it differs from them in being placed on the baseline o ...
/code> that we want to map into a new list X' according to the function f(x) = x + 1 : The map is provided as part of the Haskell's base prelude (i.e. "standard library") and is implemented as: map :: (a -> b) -> -> map _ [] = [] map f (x : xs) = f x : map f xs


Generalization

In Haskell, the polymorphic function map :: (a -> b) -> -> /code> is generalized to a
polytypic function In programming language theory and type theory, polymorphism is the provision of a single interface (computing), interface to entities of different Data type, types or the use of a single symbol to represent multiple different types.: "Polymorph ...
fmap :: Functor f => (a -> b) -> f a -> f b, which applies to any type belonging the Functor
type class In computer science, a type class is a type system construct that supports ad hoc polymorphism. This is achieved by adding constraints to type variables in parametrically polymorphic types. Such a constraint typically involves a type class T a ...
. The type constructor of lists [] can be defined as an instance of the Functor type class using the map function from the previous example: instance Functor [] where fmap = map Other examples of Functor instances include trees: -- a simple binary tree data Tree a = Leaf a , Fork (Tree a) (Tree a) instance Functor Tree where fmap f (Leaf x) = Leaf (f x) fmap f (Fork l r) = Fork (fmap f l) (fmap f r) Mapping over a tree yields: >>> fmap square (Fork (Fork (Leaf 1) (Leaf 2)) (Fork (Leaf 3) (Leaf 4))) Fork (Fork (Leaf 1) (Leaf 4)) (Fork (Leaf 9) (Leaf 16)) For every instance of the Functor type class, fmap is contractually obliged to obey the functor laws: fmap id ≡ id -- identity law fmap (f . g) ≡ fmap f . fmap g -- composition law where . denotes
function composition In mathematics, function composition is an operation that takes two functions and , and produces a function such that . In this operation, the function is applied to the result of applying the function to . That is, the functions and ...
in Haskell. Among other uses, this allows defining element-wise operations for various kinds of collections. Moreover, if and are two functors, a
natural transformation In category theory, a branch of mathematics, a natural transformation provides a way of transforming one functor into another while respecting the internal structure (i.e., the composition of morphisms) of the categories involved. Hence, a na ...
is a function of polymorphic type h : \forall T . F(T) \to G(T) which respects : : h_Y \circ \operatorname(f) = \operatorname(f) \circ h_X for any function f : X \to Y. If the function is defined by parametric polymorphism as in the type definition above, this specification is always satisfied.


Optimizations

The mathematical basis of maps allow for a number of optimizations. The composition law ensures that both * (map f . map g) list and * map (f . g) list lead to the same result; that is, \operatorname(f) \circ \operatorname(g) = \operatorname(f \circ g). However, the second form is more efficient to compute than the first form, because each map requires rebuilding an entire list from scratch. Therefore, compilers will attempt to transform the first form into the second; this type of optimization is known as ''map fusion'' and is the
functional Functional may refer to: * Movements in architecture: ** Functionalism (architecture) ** Form follows function * Functional group, combination of atoms within molecules * Medical conditions without currently visible organic basis: ** Functional s ...
analog of loop fusion. Map functions can be and often are defined in terms of a
fold Fold, folding or foldable may refer to: Arts, entertainment, and media * ''Fold'' (album), the debut release by Australian rock band Epicure *Fold (poker), in the game of poker, to discard one's hand and forfeit interest in the current pot *Above ...
such as foldr, which means one can do a ''map-fold fusion'': foldr f z . map g is equivalent to foldr (f . g) z. The implementation of map above on singly linked lists is not
tail-recursive In computer science, a tail call is a subroutine call performed as the final action of a procedure. If the target of a tail is the same subroutine, the subroutine is said to be tail recursive, which is a special case of direct recursion. Tail recu ...
, so it may build up a lot of frames on the stack when called with a large list. Many languages alternately provide a "reverse map" function, which is equivalent to reversing a mapped list, but is tail-recursive. Here is an implementation which utilizes the
fold Fold, folding or foldable may refer to: Arts, entertainment, and media * ''Fold'' (album), the debut release by Australian rock band Epicure *Fold (poker), in the game of poker, to discard one's hand and forfeit interest in the current pot *Above ...
-left function. reverseMap f = foldl (\ys x -> f x : ys) [] Since reversing a singly linked list is also tail-recursive, reverse and reverse-map can be composed to perform normal map in a tail-recursive way, though it requires performing two passes over the list.


Language comparison

The map function originated in
functional programming In computer science, functional programming is a programming paradigm where programs are constructed by applying and composing functions. It is a declarative programming paradigm in which function definitions are trees of expressions that ...
languages. The language
Lisp A lisp is a speech impairment in which a person misarticulates sibilants (, , , , , , , ). These misarticulations often result in unclear speech. Types * A frontal lisp occurs when the tongue is placed anterior to the target. Interdental lispi ...
introduced a map function called maplist in 1959, with slightly different versions already appearing in 1958. This is the original definition for maplist, mapping a function over successive rest lists:
maplist ;f=  ull[x-> NIL;T -> cons[f[x">.html" ;"title="ull[x">ull[x-> NIL;T -> cons[f[xmaplist[cdr[x">">ull[x<_a>->_NIL;T_->_cons[f[x.html" ;"title=".html" ;"title="ull[x">ull[x-> NIL;T -> cons[f[x">.html" ;"title="ull[x">ull[x-> NIL;T -> cons[f[xmaplist[cdr[xf]
The function maplist is still available in newer Lisps like
Common Lisp Common Lisp (CL) is a dialect of the Lisp programming language, published in ANSI standard document ''ANSI INCITS 226-1994 (S20018)'' (formerly ''X3.226-1994 (R1999)''). The Common Lisp HyperSpec, a hyperlinked HTML version, has been derived fr ...
,Function MAPC, MAPCAR, MAPCAN, MAPL, MAPLIST, MAPCON in ANSI Common Lisp
/ref> though functions like mapcar or the more generic map would be preferred. Squaring the elements of a list using maplist would be written in
S-expression In computer programming, an S-expression (or symbolic expression, abbreviated as sexpr or sexp) is an expression in a like-named notation for nested list (tree-structured) data. S-expressions were invented for and popularized by the programming la ...
notation like this: (maplist (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 Procedural may refer to: * Procedural generation, a term used in computer graphics applications *Procedural knowledge, the knowledge exercised in the performance of some task * Procedural law, a legal concept *Procedural memory, a cognitive scienc ...
,
object-oriented Object-oriented programming (OOP) is a programming paradigm based on the concept of " objects", which can contain data and code. The data is in the form of fields (often known as attributes or ''properties''), and the code is in the form of ...
, and
multi-paradigm Programming paradigms are a way to classify programming languages based on their features. Languages can be classified into multiple paradigms. Some paradigms are concerned mainly with implications for the execution model of the language, su ...
languages as well: In C++'s Standard 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
ColdFusion Markup Language ColdFusion Markup Language, more commonly known as CFML, is a scripting language for web development that runs on the JVM, the .NET framework, and Google App Engine. Multiple commercial and open source implementations of CFML engines are availab ...
(CFML),
Perl Perl is a family of two High-level programming language, high-level, General-purpose programming language, general-purpose, Interpreter (computing), interpreted, dynamic programming languages. "Perl" refers to Perl 5, but from 2000 to 2019 it ...
, Python, and
Ruby A ruby is a pinkish red to blood-red colored gemstone, a variety of the mineral corundum (aluminium oxide). Ruby is one of the most popular traditional jewelry gems and is very durable. Other varieties of gem-quality corundum are called sapp ...
; the operation is called map in all four of these languages. A collect alias for map is also provided in Ruby (from
Smalltalk Smalltalk is an object-oriented, dynamically typed reflective programming language. It was designed and created in part for educational use, specifically for constructionist learning, at the Learning Research Group (LRG) of Xerox PARC by ...
).
Common Lisp Common Lisp (CL) is a dialect of the Lisp programming language, published in ANSI standard document ''ANSI INCITS 226-1994 (S20018)'' (formerly ''X3.226-1994 (R1999)''). The Common Lisp HyperSpec, a hyperlinked HTML version, has been derived fr ...
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 function In mathematics and in computer programming, a variadic function is a function of indefinite arity, i.e., one which accepts a variable number of arguments. Support for variadic functions differs widely among programming languages. The term ''var ...
s may have versions of map with variable
arity Arity () is the number of arguments or operands taken by a function, operation or relation in logic, mathematics, and computer science. In mathematics, arity may also be named ''rank'', but this word can have many other meanings in mathematics. In ...
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 and
currying In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments into evaluating a sequence of functions, each with a single argument. For example, currying a function f tha ...
, map may be partially applied to ''lift'' a function that works on only one value to an element-wise equivalent that works on an entire container; for example, map square is a Haskell function which squares each element of a list.


See also

*
Functor (functional programming) In functional programming, a functor is a design pattern inspired by the definition from category theory that allows one to apply a function to values inside a generic type without changing the structure of the generic type. In Haskell this idea ...
*
Zipping (computer science) In computer science, zipping is a function which maps a tuple of sequences into a sequence of tuples. This name zip derives from the action of a zipper in that it interleaves two formerly disjoint sequences. The inverse function is ''unzip''. E ...
or zip, mapping 'list' over multiple lists * Filter (higher-order function) * Fold (higher-order function) * foreach * Free monoid *
Functional programming In computer science, functional programming is a programming paradigm where programs are constructed by applying and composing functions. It is a declarative programming paradigm in which function definitions are trees of expressions that ...
* Higher-order function *
List comprehension A list comprehension is a syntactic construct available in some programming languages for creating a list based on existing lists. It follows the form of the mathematical ''set-builder notation'' (''set comprehension'') as distinct from the use of ...
* Map (parallel pattern)


References

{{Reflist Higher-order functions Programming language comparisons Articles with example Haskell code Iteration in programming