---
title: "Functional Operations"
language: "en"
type: "Tech Note"
summary: "In an expression like f[x], the function name f is itself an expression, and you can treat it as you would any other expression. The ability to treat the names of functions just like other kinds of expressions is an important consequence of the symbolic nature of the Wolfram Language. It makes possible the whole range of functional operations. Ordinary Wolfram Language functions such as Log or Integrate typically operate on data such as numbers and algebraic expressions. Wolfram Language functions that represent functional operations, however, can operate not only on ordinary data, but also on functions themselves. Thus, for example, the functional operation InverseFunction takes a Wolfram Language function name as an argument, and represents the inverse of that function."
keywords: 
- #
- &
- ##
- accumulate
- all parts of expressions
- ampersand
- anonymous functions
- apply
- applying functions
- arguments
- array
- associativity
- binary operators
- bound variables
- cascade
- choose elements
- collating
- commutativity
- compiled function
- CompiledFunction
- compose list
- ComposeList
- composition
- composition of functions
- compress in APL
- continued fractions
- criteria
- cumulative sums
- cycle detection
- deleting elements
- depth-first walks
- derivative
- dimensions
- discard list elements
- distribute
- distributivity
- elements of expressions
- expansion
- expressions
- expression walking
- filtering lists
- first occurrence
- FixedPoint
- FixedPointList
- flatten
- FlattenAt
- fold
- FoldList
- formal logic
- formal parameters
- function
- functional composition
- functional programming
- functionals
- function names
- functions
- hash sign
- heads
- identity
- indexed functions
- indices
- inner
- interpolating function
- InterpolatingFunction
- InverseFunction
- iterated functions
- iteration
- lambda expressions
- least fixed point
- levels
- linearity
- LinearSolveFunction
- listability
- lists
- map
- MapAll
- MapAt
- MapIndexed
- MapThread
- matrices
- multiple arguments
- mu operator
- names
- nest
- NestList
- NestWhile
- NestWhileList
- newtons approximation
- number sign
- Octothorp
- operate
- operations
- operators
- order
- OrderedQ
- ordering
- outer
- parallel form of Map
- parallel operations
- parameters
- parts of expressions
- permutations
- picking elements of lists
- position
- positions
- pounds sign
- precedence
- predicates
- prefix operation
- pure functions
- ranking
- ravel in APL
- reduce in APL
- removing sublists
- repetitive operations
- rest
- runs of arguments
- satisfying criterion
- Scan
- scratch mark
- select
- sequence
- Sharp
- slot
- SlotSequence
- sort
- sorting
- splicing
- squash
- structural operations
- subexpressions
- Sublists
- subsets
- symbolic systems
- symmetric functions
- templates
- tensors
- thread
- threading
- through
- tree walking
- Unary operators
- unpack
- unravel
- until
- variables
- walking through expressions
- while
- wrapping functions around elements of lists
- zip
canonical_url: "https://reference.wolfram.com/language/tutorial/FunctionalOperations.html"
source: "Wolfram Language Documentation"
related_guides: 
  - 
    title: "Functional Programming"
    link: "https://reference.wolfram.com/language/guide/FunctionalProgramming.en.md"
related_functions: 
  - 
    title: "All"
    link: "https://reference.wolfram.com/language/ref/All.en.md"
  - 
    title: "Apply"
    link: "https://reference.wolfram.com/language/ref/Apply.en.md"
  - 
    title: "Array"
    link: "https://reference.wolfram.com/language/ref/Array.en.md"
  - 
    title: "Compile"
    link: "https://reference.wolfram.com/language/ref/Compile.en.md"
  - 
    title: "CompiledFunction"
    link: "https://reference.wolfram.com/language/ref/CompiledFunction.en.md"
  - 
    title: "ComposeList"
    link: "https://reference.wolfram.com/language/ref/ComposeList.en.md"
  - 
    title: "Composition"
    link: "https://reference.wolfram.com/language/ref/Composition.en.md"
  - 
    title: "Distribute"
    link: "https://reference.wolfram.com/language/ref/Distribute.en.md"
  - 
    title: "False"
    link: "https://reference.wolfram.com/language/ref/False.en.md"
  - 
    title: "FixedPoint"
    link: "https://reference.wolfram.com/language/ref/FixedPoint.en.md"
  - 
    title: "FixedPointList"
    link: "https://reference.wolfram.com/language/ref/FixedPointList.en.md"
  - 
    title: "Flatten"
    link: "https://reference.wolfram.com/language/ref/Flatten.en.md"
  - 
    title: "FlattenAt"
    link: "https://reference.wolfram.com/language/ref/FlattenAt.en.md"
  - 
    title: "Fold"
    link: "https://reference.wolfram.com/language/ref/Fold.en.md"
  - 
    title: "FoldList"
    link: "https://reference.wolfram.com/language/ref/FoldList.en.md"
  - 
    title: "Function"
    link: "https://reference.wolfram.com/language/ref/Function.en.md"
  - 
    title: "Heads"
    link: "https://reference.wolfram.com/language/ref/Heads.en.md"
  - 
    title: "Identity"
    link: "https://reference.wolfram.com/language/ref/Identity.en.md"
  - 
    title: "Inner"
    link: "https://reference.wolfram.com/language/ref/Inner.en.md"
  - 
    title: "InterpolatingFunction"
    link: "https://reference.wolfram.com/language/ref/InterpolatingFunction.en.md"
  - 
    title: "Interpolation"
    link: "https://reference.wolfram.com/language/ref/Interpolation.en.md"
  - 
    title: "InverseFunction"
    link: "https://reference.wolfram.com/language/ref/InverseFunction.en.md"
  - 
    title: "LinearSolve"
    link: "https://reference.wolfram.com/language/ref/LinearSolve.en.md"
  - 
    title: "LinearSolveFunction"
    link: "https://reference.wolfram.com/language/ref/LinearSolveFunction.en.md"
  - 
    title: "Map"
    link: "https://reference.wolfram.com/language/ref/Map.en.md"
  - 
    title: "MapAll"
    link: "https://reference.wolfram.com/language/ref/MapAll.en.md"
  - 
    title: "MapApply"
    link: "https://reference.wolfram.com/language/ref/MapApply.en.md"
  - 
    title: "MapAt"
    link: "https://reference.wolfram.com/language/ref/MapAt.en.md"
  - 
    title: "MapIndexed"
    link: "https://reference.wolfram.com/language/ref/MapIndexed.en.md"
  - 
    title: "MapThread"
    link: "https://reference.wolfram.com/language/ref/MapThread.en.md"
  - 
    title: "NDSolve"
    link: "https://reference.wolfram.com/language/ref/NDSolve.en.md"
  - 
    title: "Nest"
    link: "https://reference.wolfram.com/language/ref/Nest.en.md"
  - 
    title: "NestList"
    link: "https://reference.wolfram.com/language/ref/NestList.en.md"
  - 
    title: "NestWhile"
    link: "https://reference.wolfram.com/language/ref/NestWhile.en.md"
  - 
    title: "NestWhileList"
    link: "https://reference.wolfram.com/language/ref/NestWhileList.en.md"
  - 
    title: "Operate"
    link: "https://reference.wolfram.com/language/ref/Operate.en.md"
  - 
    title: "Order"
    link: "https://reference.wolfram.com/language/ref/Order.en.md"
  - 
    title: "OrderedQ"
    link: "https://reference.wolfram.com/language/ref/OrderedQ.en.md"
  - 
    title: "Ordering"
    link: "https://reference.wolfram.com/language/ref/Ordering.en.md"
  - 
    title: "Outer"
    link: "https://reference.wolfram.com/language/ref/Outer.en.md"
  - 
    title: "RightComposition"
    link: "https://reference.wolfram.com/language/ref/RightComposition.en.md"
  - 
    title: "Scan"
    link: "https://reference.wolfram.com/language/ref/Scan.en.md"
  - 
    title: "Select"
    link: "https://reference.wolfram.com/language/ref/Select.en.md"
  - 
    title: "Sequence"
    link: "https://reference.wolfram.com/language/ref/Sequence.en.md"
  - 
    title: "Sort"
    link: "https://reference.wolfram.com/language/ref/Sort.en.md"
  - 
    title: "Thread"
    link: "https://reference.wolfram.com/language/ref/Thread.en.md"
  - 
    title: "Through"
    link: "https://reference.wolfram.com/language/ref/Through.en.md"
  - 
    title: "True"
    link: "https://reference.wolfram.com/language/ref/True.en.md"
---
# Functional Operations

## Function Names as Expressions

In an expression like ``f[x]``, the "function name" ``f`` is itself an expression, and you can treat it as you would any other expression.

You can replace names of functions using transformation rules:

```wl
In[1]:=  f[x] + f[1 - x] /. f -> g

Out[1]=  g[1 - x] + g[x]
```

Any assignments you have made are used on function names:

```wl
In[2]:=  p1 = p2;p1[x, y]

Out[2]=  p2[x, y]
```

This defines a function which takes a function name as an argument:

```wl
In[3]:=  pf[f_, x_] := f[x] + f[1 - x]
```

This gives ``Log`` as the function name to use:

```wl
In[4]:=  pf[Log, q]

Out[4]=  Log[1 - q] + Log[q]
```

The ability to treat the names of functions just like other kinds of expressions is an important consequence of the symbolic nature of the Wolfram Language. It makes possible the whole range of *functional operations*.

Ordinary Wolfram Language functions such as ``Log`` or ``Integrate`` typically operate on data such as numbers and algebraic expressions. Wolfram Language functions that represent functional operations, however, can operate not only on ordinary data, but also on functions themselves. Thus, for example, the functional operation ``InverseFunction`` takes a Wolfram Language function name as an argument, and represents the inverse of that function.

``InverseFunction`` is a functional operation: it takes a Wolfram Language function as an argument, and returns another function which represents its inverse:

```wl
In[5]:=  InverseFunction[ArcSin]

Out[5]=  Sin
```

The result obtained from ``InverseFunction`` is a function which you can apply to data:

```wl
In[6]:=  %[x]

Out[6]=  Sin[x]
```

You can also use ``InverseFunction`` in a purely symbolic way:

```wl
In[7]:=  InverseFunction[f][x]

Out[7]=  f^(-1)[x]
```

There are many kinds of functional operations in the Wolfram Language. Some represent mathematical operations; others represent various kinds of procedures and algorithms.

Unless you are familiar with advanced symbolic languages, you will probably not recognize most of the functional operations discussed. At first, the operations may seem difficult to understand. But it is worth persisting. Functional operations provide one of the most conceptually and practically efficient ways to use the Wolfram Language.

## Applying Functions Repeatedly

Many programs you write will involve operations that need to be iterated several times. ``Nest`` and ``NestList`` are powerful constructs for doing this.

|     |     |
| --- | --- |
| Nest[f, x, n] | apply the function f nested n times to x |
| NestList[f, x, n] | generate the list $$\{\text{\textit{$x$}},\text{\textit{$f$}}[\text{\textit{$x$}}],\text{\textit{$f$}}[\text{\textit{$f$}}[\text{\textit{$x$}}]],\ldots \}$$, where f is nested up to n deep |

*Applying functions of one argument repeatedly.*

``Nest[f, x, n]`` takes the "name" ``f`` of a function, and applies the function ``n`` times to ``x`` :

```wl
In[1]:=  Nest[f, x, 4]

Out[1]=  f[f[f[f[x]]]]
```

This makes a list of each successive nesting:

```wl
In[2]:=  NestList[f, x, 4]

Out[2]=  {x, f[x], f[f[x]], f[f[f[x]]], f[f[f[f[x]]]]}
```

Here is a simple function:

```wl
In[3]:=  recip[x_] := 1 / (1 + x)
```

You can iterate the function using ``Nest`` :

```wl
In[4]:=  Nest[recip, x, 3]

Out[4]=  (1/1 + (1/1 + (1/1 + x)))
```

``Nest`` and ``NestList`` allow you to apply functions a fixed number of times. Often you may want to apply functions until the result no longer changes. You can do this using ``FixedPoint`` and ``FixedPointList``.

|     |     |
| --- | --- |
| FixedPoint[f, x] | apply the function f repeatedly until the result no longer changes |
| FixedPointList[f, x] | generate the list $$\{\text{\textit{$x$}},\text{\textit{$f$}}[\text{\textit{$x$}}],\text{\textit{$f$}}[\text{\textit{$f$}}[\text{\textit{$x$}}]],\ldots \}$$, stopping when the elements no longer change |

*Applying functions until the result no longer changes.*

Here is a function that takes one step in Newton’s approximation to $\sqrt{3}$ :

```wl
In[5]:=  newton3[x_] := N[1 / 2 (x + 3 / x)]
```

Here are five successive iterates of the function, starting at $x=1$ :

```wl
In[6]:=  NestList[newton3, 1.0, 5]

Out[6]=  {1., 2., 1.75, 1.73214, 1.73205, 1.73205}
```

Using the function ``FixedPoint``, you can automatically continue applying ``newton3`` until the result no longer changes:

```wl
In[7]:=  FixedPoint[newton3, 1.0]

Out[7]=  1.73205
```

Here is the sequence of results:

```wl
In[8]:=  FixedPointList[newton3, 1.0]

Out[8]=  {1., 2., 1.75, 1.73214, 1.73205, 1.73205, 1.73205}
```

|     |     |
| --- | --- |
| NestWhile[f, x, test] | apply the function f repeatedly until applying test to the result no longer yields True |
| NestWhileList[f, x, test] | generate the list $$\{\text{\textit{$x$}},\text{\textit{$f$}}[\text{\textit{$x$}}],\text{\textit{$ ... text{\textit{$x$}}]],\ldots \}$$, stopping when applying test to the result no longer yields True |
| NestWhile[f, x, test, m],  NestWhileList[f, x, test, m] |     |
|     | supply the m most recent results as arguments for test at each step |
| NestWhile[f, x, test, All],  NestWhileList[f, x, test, All] |     |
|     | supply all results so far as arguments for test |

*Applying functions repeatedly until a test fails.*

Here is a function which divides a number by 2:

```wl
In[9]:=  divide2[n_] := n / 2
```

This repeatedly applies ``divide2`` until the result is no longer an even number:

```wl
In[10]:=  NestWhileList[divide2, 123456, EvenQ]

Out[10]=  {123456, 61728, 30864, 15432, 7716, 3858, 1929}
```

This repeatedly applies ``newton3``, stopping when two successive results are no longer considered unequal, just as in ``FixedPointList`` :

```wl
In[11]:=  NestWhileList[newton3, 1.0, Unequal, 2]

Out[11]=  {1., 2., 1.75, 1.73214, 1.73205, 1.73205, 1.73205}
```

This goes on until the first time a result that has been seen before reappears:

```wl
In[12]:=  NestWhileList[Mod[5#, 7]&, 1, Unequal, All]

Out[12]=  {1, 5, 4, 6, 2, 3, 1}
```

Operations such as ``Nest`` take a function ``f`` of one argument, and apply it repeatedly. At each step, they use the result of the previous step as the new argument of ``f``.

It is important to generalize this notion to functions of two arguments. You can again apply the function repeatedly, but now each result you get supplies only one of the new arguments you need. A convenient approach is to get the other argument at each step from the successive elements of a list.

|     |     |
| --- | --- |
| FoldList[f, x, {a, b, …}] | create the list $$\{\text{\textit{$x$}},\text{\textit{$f$}}[\text{\textit{$x$}},\text{\textit{$a$} ... $}}[\text{\textit{$f$}}[\text{\textit{$x$}},\text{\textit{$a$}}],\text{\textit{$b$}}],\ldots \}$$ |
| Fold[f, x, {a, b, …}] | give the last element of the list produced by FoldList[f, x, {a, b, …}] |

*Ways to repeatedly apply functions of two arguments.*

Here is an example of what ``FoldList`` does:

```wl
In[13]:=  FoldList[f, x, {a, b, c}]

Out[13]=  {x, f[x, a], f[f[x, a], b], f[f[f[x, a], b], c]}
```

``Fold`` gives the last element of the list produced by ``FoldList`` :

```wl
In[14]:=  Fold[f, x, {a, b, c}]

Out[14]=  f[f[f[x, a], b], c]
```

This gives a list of cumulative sums:

```wl
In[15]:=  FoldList[Plus, 0, {a, b, c}]

Out[15]=  {0, a, a + b, a + b + c}
```

Using ``Fold`` and ``FoldList`` you can write many elegant and efficient programs in the Wolfram Language. In some cases, you may find it helpful to think of ``Fold`` and ``FoldList`` as producing a simple nesting of a family of functions indexed by their second argument.

This defines a function ``nextdigit`` :

```wl
In[16]:=  nextdigit[a_, b_] := 10 a + b
```

This is now like the built‐in function ``FromDigits`` :

```wl
In[17]:=  fromdigits[digits_] := Fold[nextdigit, 0, digits]
```

Here is an example of the function in action:

```wl
In[18]:=  fromdigits[{1, 3, 7, 2, 9, 1}]

Out[18]=  137291
```

## Applying Functions to Lists and Other Expressions

In an expression like ``f[{a, b, c}]`` you are giving a list as the argument to a function. Often you need instead to apply a function directly to the elements of a list, rather than to the list as a whole. You can do this in the Wolfram Language using ``Apply``.

This makes each element of the list an argument of the function ``f`` :

```wl
In[1]:= Apply[f, {a, b, c}]

Out[1]= f[a, b, c]
```

This gives ``Times[a, b, c]`` which yields the product of the elements in the list:

```wl
In[2]:= Apply[Times, {a, b, c}]

Out[2]= a b c
```

Here is a definition of a function that works like the built-in function ``GeometricMean``, written using ``Apply`` :

```wl
In[3]:= geom[list_] := Apply[Times, list] ^ (1 / Length[list])
```

|                                   |                                                  |
| --------------------------------- | ------------------------------------------------ |
| Apply[f, {a, b, …}]               | apply f to a list, giving f[a, b, …]             |
| Apply[f, expr]   or   f@@expr     | apply f to the top level of an expression        |
| MapApply[f, expr]   or   f@@@expr | apply f at the first level in an expression      |
| Apply[f, expr, {1}]               | equivalent to f@@@expr                           |
| Apply[f, expr, lev]               | apply f at the specified levels in an expression |

*Applying functions to lists and other expressions.*

What ``Apply`` does in general is to replace the head of an expression with the function you specify. Here it replaces ``Plus`` by ``List`` :

```wl
In[4]:=  Apply[List, a + b + c]

Out[4]=  {a, b, c}
```

Here is a matrix:

```wl
In[2]:= m = {{a, b, c}, {b, c, d}}

Out[2]= {{a, b, c}, {b, c, d}}
```

Using ``Apply`` without an explicit level specification replaces the top‐level list with ``f`` :

```wl
In[6]:=  Apply[f, m]

Out[6]=  f[{a, b, c}, {b, c, d}]
```

This applies ``f`` only to parts of ``m`` at level 1:

```wl
In[7]:=  Apply[f, m, {1}]

Out[7]=  {f[a, b, c], f[b, c, d]}
```

``MapApply`` is equivalent to using ``Apply`` on parts at level 1:

```wl
In[3]:= MapApply[f, m]

Out[3]= {f[a, b, c], f[b, c, d]}
```

This applies ``f`` at levels 0 through 1:

```wl
In[8]:=  Apply[f, m, {0, 1}]

Out[8]=  f[f[a, b, c], f[b, c, d]]
```

## Applying Functions to Parts of Expressions

If you have a list of elements, it is often important to be able to apply a function separately to each of the elements. You can do this in the Wolfram Language using ``Map``.

This applies ``f`` separately to each element in a list:

```wl
In[1]:=  Map[f, {a, b, c}]

Out[1]=  {f[a], f[b], f[c]}
```

This defines a function which takes the first two elements from a list:

```wl
In[2]:=  take2[list_] := Take[list, 2]
```

You can use ``Map`` to apply ``take2`` to each element of a list:

```wl
In[3]:=  Map[take2, {{1, 3, 4}, {5, 6, 7}, {2, 1, 6, 6}}]

Out[3]=  {{1, 3}, {5, 6}, {2, 1}}
```

|                   |                                                            |
| ----------------- | ---------------------------------------------------------- |
| Map[f, {a, b, …}] | apply f to each element in a list, giving {f[a], f[b], …}  |

*Applying a function to each element in a list.*

What ``Map[f, expr]`` effectively does is to "wrap" the function ``f`` around each element of the expression ``expr``. You can use ``Map`` on any expression, not just a list.

This applies ``f`` to each element in the sum:

```wl
In[4]:=  Map[f, a + b + c]

Out[4]=  f[a] + f[b] + f[c]
```

This applies ``Sqrt`` to each argument of ``g`` :

```wl
In[5]:=  Map[Sqrt, g[x ^ 2, x ^ 3]]

Out[5]=  g[Sqrt[x^2], Sqrt[x^3]]
```

``Map[f, expr]`` applies ``f`` to the first level of parts in ``expr``. You can use ``MapAll[f, expr]`` to apply ``f`` to *all* the parts of ``expr``.

This defines a 2x2 matrix ``m`` :

```wl
In[6]:=  m = {{a, b}, {c, d}}

Out[6]=  {{a, b}, {c, d}}
```

``Map`` applies ``f`` to the first level of ``m``, in this case the rows of the matrix:

```wl
In[7]:=  Map[f, m]

Out[7]=  {f[{a, b}], f[{c, d}]}
```

``MapAll`` applies ``f`` at *all* levels in ``m``. If you look carefully at this expression, you will see an ``f`` wrapped around every part:

```wl
In[8]:=  MapAll[f, m]

Out[8]=  f[{f[{f[a], f[b]}], f[{f[c], f[d]}]}]
```

In general, you can use level specifications as described in ["Levels in Expressions"](https://reference.wolfram.com/language/tutorial/Expressions.en.md#31184) to tell ``Map`` to which parts of an expression to apply your function.

This applies ``f`` only to the parts of ``m`` at level 2:

```wl
In[9]:=  Map[f, m, {2}]

Out[9]=  {{f[a], f[b]}, {f[c], f[d]}}
```

Setting the option ``Heads -> True`` wraps ``f`` around the head of each part, as well as its elements:

```wl
In[10]:=  Map[f, m, Heads -> True]

Out[10]=  f[List][f[{a, b}], f[{c, d}]]
```

|                                 |                                                         |
| ------------------------------- | ------------------------------------------------------- |
| Map[f, expr]  or  f /@ expr     | apply f to the first‐level parts of expr                |
| MapAll[f, expr]  or  f //@ expr | apply f to all parts of expr                            |
| Map[f, expr, lev]               | apply f to each part of expr at levels specified by lev |

*Ways to apply a function to different parts of expressions.*

Level specifications allow you to tell ``Map`` to which levels of parts in an expression you want a function applied. With ``MapAt``, however, you can instead give an explicit list of parts where you want a function applied. You specify each part by giving its indices, as discussed in ["Parts of Expressions"](https://reference.wolfram.com/language/tutorial/Expressions.en.md#24855).

Here is a 2x3 matrix:

```wl
In[11]:=  mm = {{a, b, c}, {b, c, d}}

Out[11]=  {{a, b, c}, {b, c, d}}
```

This applies ``f`` to parts ``{1, 2}`` and ``{2, 3}`` :

```wl
In[12]:=  MapAt[f, mm, {{1, 2}, {2, 3}}]

Out[12]=  {{a, f[b], c}, {b, c, f[d]}}
```

This gives a list of the positions at which ``b`` occurs in ``mm`` :

```wl
In[13]:=  Position[mm, b]

Out[13]=  {{1, 2}, {2, 1}}
```

You can feed the list of positions you get from ``Position`` directly into ``MapAt`` :

```wl
In[14]:=  MapAt[f, mm, %]

Out[14]=  {{a, f[b], c}, {f[b], c, d}}
```

To avoid ambiguity, you must put each part specification in a list, even when it involves only one index:

```wl
In[15]:=  MapAt[f, {a, b, c, d}, {{2}, {3}}]

Out[15]=  {a, f[b], f[c], d}
```

|                                   |                                    |
| --------------------------------- | ---------------------------------- |
| MapAt[f, expr, {part1, part2, …}] | apply f to specified parts of expr |

*Applying a function to specific parts of an expression.*

Here is an expression:

```wl
In[16]:=  t = 1 + (3 + x) ^ 2 / x

Out[16]=  1 + ((3 + x)^2/x)
```

This is the full form of ``t`` :

```wl
In[17]:=  FullForm[t]

Out[17]//FullForm=  Plus[1, Times[Power[x, -1], Power[Plus[3, x], 2]]]
```

You can use ``MapAt`` on any expression. Remember that parts are numbered on the basis of the full forms of expressions:

```wl
In[18]:=  MapAt[f, t, {{2, 1, 1}, {2, 2}}]

Out[18]=  1 + (f[(3 + x)^2]/f[x])
```

|     |     |
| --- | --- |
| MapIndexed[f, expr] | apply f to the elements of an expression, giving the part specification of each element as a second argument to f |
| MapIndexed[f, expr, lev] | apply f to parts at specified levels, giving the list of indices for each part as a second argument to f |

*Applying a function to parts and their indices.*

This applies ``f`` to each element in a list, giving the index of the element as a second argument to ``f`` :

```wl
In[19]:=  MapIndexed[f, {a, b, c}]

Out[19]=  {f[a, {1}], f[b, {2}], f[c, {3}]}
```

This applies ``f`` to both levels in a matrix:

```wl
In[20]:=  MapIndexed[f, {{a, b}, {c, d}}, 2]

Out[20]=  {f[{f[a, {1, 1}], f[b, {1, 2}]}, {1}], f[{f[c, {2, 1}], f[d, {2, 2}]}, {2}]}
```

``Map`` allows you to apply a function of one argument to parts of an expression. Sometimes, however, you may instead want to apply a function of several arguments to corresponding parts of several different expressions. You can do this using ``MapThread``.

|                                      |                                                        |
| ------------------------------------ | ------------------------------------------------------ |
| MapThread[f, {expr1, expr2, …}]      | apply f to corresponding elements in each of the expri |
| MapThread[f, {expr1, expr2, …}, lev] | apply f to parts of the expri at the specified level   |

*Applying a function to several expressions at once.*

This applies ``f`` to corresponding pairs of list elements:

```wl
In[21]:=  MapThread[f, {{a, b, c}, {ap, bp, cp}}]

Out[21]=  {f[a, ap], f[b, bp], f[c, cp]}
```

``MapThread`` works with any number of expressions, so long as they have the same structure:

```wl
In[22]:=  MapThread[f, {{a, b}, {ap, bp}, {app, bpp}}]

Out[22]=  {f[a, ap, app], f[b, bp, bpp]}
```

Functions like ``Map`` allow you to create expressions with parts modified. Sometimes you simply want to go through an expression, and apply a particular function to some parts of it, without building a new expression. A typical case is when the function you apply has certain “side effects”, such as making assignments, or generating output.

|                    |                                                                |
| ------------------ | -------------------------------------------------------------- |
| Scan[f, expr]      | evaluate f applied to each element of expr in turn             |
| Scan[f, expr, lev] | evaluate f applied to parts of expr on levels specified by lev |

*Evaluating functions on parts of expressions.*

``Map`` constructs a new list in which ``f`` has been applied to each element of the list:

```wl
In[23]:=  Map[f, {a, b, c}]

Out[23]=  {f[a], f[b], f[c]}
```

``Scan`` evaluates the result of applying a function to each element, but does not construct a new expression:

```wl
In[24]:=  Scan[Print, {a, b, c}]

a

b

c
```

``Scan`` visits the parts of an expression in a depth‐first walk, with the leaves visited first:

```wl
In[25]:=  Scan[Print, 1 + x ^ 2, Infinity]

1

x

2

x^2
```

## Pure Functions

|                             |                                                                           |
| --------------------------- | ------------------------------------------------------------------------- |
| Function[x, body]           | a pure function in which x is replaced by any argument you provide        |
| Function[{x1, x2, …}, body] | a pure function that takes several arguments                              |
| body&                       | a pure function in which arguments are specified as # or #1, #2, #3, etc. |

*Pure functions.*

When you use functional operations such as ``Nest`` and ``Map``, you always have to specify a function to apply. In all the examples above, we have used the "name" of a function to specify the function. Pure functions allow you to give functions which can be applied to arguments, without having to define explicit names for the functions.

This defines a function ``h`` :

```wl
In[1]:=  h[x_] := f[x] + g[x]
```

Having defined ``h``, you can now use its name in ``Map`` :

```wl
In[2]:=  Map[h, {a, b, c}]

Out[2]=  {f[a] + g[a], f[b] + g[b], f[c] + g[c]}
```

Here is a way to get the same result using a pure function:

```wl
In[3]:=  Map[f[#] + g[#]&, {a, b, c}]

Out[3]=  {f[a] + g[a], f[b] + g[b], f[c] + g[c]}
```

There are several equivalent ways to write pure functions in the Wolfram Language. The idea in all cases is to construct an object which, when supplied with appropriate arguments, computes a particular function. Thus, for example, if ``fun`` is a pure function, then ``fun[a]`` evaluates the function with argument ``a``.

Here is a pure function that represents the operation of squaring:

```wl
In[4]:=  Function[x, x ^ 2]

Out[4]=  Function[x, x^2]
```

Supplying the argument ``n`` to the pure function yields the square of ``n`` :

```wl
In[5]:=  %[n]

Out[5]=  n^2
```

You can use a pure function wherever you would usually give the name of a function.

You can use a pure function in ``Map`` :

```wl
In[6]:=  Map[Function[x, x ^ 2], a + b + c]

Out[6]=  a^2 + b^2 + c^2
```

Or in ``Nest`` :

```wl
In[7]:=  Nest[Function[q, 1 / (1 + q)], x, 3]

Out[7]=  (1/1 + (1/1 + (1/1 + x)))
```

This sets up a pure function with two arguments and then applies the function to the arguments ``a`` and ``b`` :

```wl
In[8]:=  Function[{x, y}, x ^ 2 + y ^ 3][a, b]

Out[8]=  a^2 + b^3
```

If you are going to use a particular function repeatedly, then you can define the function using ``f[x_] := body``, and refer to the function by its name ``f``. On the other hand, if you only intend to use a function once, you will probably find it better to give the function in pure function form, without ever naming it.

If you are familiar with formal logic or the LISP programming language, you will recognize Wolfram Language pure functions as being like $\lambda$ expressions or anonymous functions. Pure functions are also close to the pure mathematical notion of operators.

|     |                                                                   |
| --- | ----------------------------------------------------------------- |
| #   | the first variable in a pure function                             |
| #n  | the n$$^{\text{th}}$$ variable in a pure function                 |
| ##  | the sequence of all variables in a pure function                  |
| ##n | the sequence of variables starting with the n$$^{\text{th}}$$ one |

*Short forms for pure functions.*

Just as the name of a function is irrelevant if you do not intend to refer to the function again, so also the names of arguments in a pure function are irrelevant. The Wolfram Language allows you to avoid using explicit names for the arguments of pure functions, and instead to specify the arguments by giving "slot numbers" ``#n``. In a Wolfram Language pure function, ``#n`` stands for the ``n``$$^{\text{th}}$$ argument you supply. ``#`` stands for the first argument.

``# ^ 2&`` is a short form for a pure function that squares its argument:

```wl
In[9]:=  Map[# ^ 2&, a + b + c]

Out[9]=  a^2 + b^2 + c^2
```

This applies a function that takes the first two elements from each list. By using a pure function, you avoid having to define the function separately:

```wl
In[10]:=  Map[Take[#, 2]&, {{2, 1, 7}, {4, 1, 5}, {3, 1, 2}}]

Out[10]=  {{2, 1}, {4, 1}, {3, 1}}
```

Using short forms for pure functions, you can simplify the definition of ``fromdigits`` given in ["Applying Functions Repeatedly"](https://reference.wolfram.com/language/tutorial/FunctionalOperations.en.md#11192) :

```wl
In[11]:=  fromdigits[digits_] := Fold[(10#1 + #2)&, 0, digits]
```

When you use short forms for pure functions, it is very important that you do not forget the ampersand. If you leave the ampersand out, the Wolfram Language will not know that the expression you give is to be used as a pure function.

When you use the ampersand notation for pure functions, you must be careful about the grouping of pieces in your input. As shown in ["Operator Input Forms"](https://reference.wolfram.com/language/tutorial/OperatorInputForms.en.md) the ampersand notation has fairly low precedence, which means that you can type expressions like ``#1 + #2&`` without parentheses. On the other hand, if you want, for example, to set an option to be a pure function, you need to use parentheses, as in ``option -> (fun&)``.

Pure functions in the Wolfram Language can take any number of arguments. You can use ``##`` to stand for all the arguments that are given, and ``##n`` to stand for the ``n``$$^{\text{th}}$$ and subsequent arguments.

``##`` stands for all arguments:

```wl
In[12]:=  f[##, ##]&[x, y]

Out[12]=  f[x, y, x, y]
```

``##2`` stands for all arguments except the first one:

```wl
In[13]:=  Apply[f[##2, #1]&, {{a, b, c}, {ap, bp}}, {1}]

Out[13]=  {f[b, c, a], f[bp, ap]}
```

## Building Lists from Functions

|                             |                                                                                             |
| --------------------------- | ------------------------------------------------------------------------------------------- |
| Array[f, n]                 | generate a length n list of the form {f[1], f[2], …}                                        |
| Array[f, {n1, n2, …}]       | generate an n1×n2×… nested list, each of whose entries consists of f applied to its indices |
| NestList[f, x, n]           | generate a list of the form {x, f[x], f[f[x]], …}, where f is nested up to n deep           |
| FoldList[f, x, {a, b, …}]   | generate a list of the form {x, f[x, a], f[f[x, a], b], …}                                  |
| ComposeList[{f1, f2, …}, x] | generate a list of the form {x, f1[x], f2[f1[x]], …}                                        |

*Making lists from functions.*

This makes a list of 5 elements, each of the form ``p[i]`` :

```wl
In[1]:=  Array[p, 5]

Out[1]=  {p[1], p[2], p[3], p[4], p[5]}
```

Here is another way to produce the same list:

```wl
In[2]:=  Table[p[i], {i, 5}]

Out[2]=  {p[1], p[2], p[3], p[4], p[5]}
```

This produces a list whose elements are $i+i^2$ :

```wl
In[3]:=  Array[# + # ^ 2&, 5]

Out[3]=  {2, 6, 12, 20, 30}
```

This generates a 2×3 matrix whose entries are ``m[i, j]`` :

```wl
In[4]:=  Array[m, {2, 3}]

Out[4]=  {{m[1, 1], m[1, 2], m[1, 3]}, {m[2, 1], m[2, 2], m[2, 3]}}
```

This generates a 3×3 matrix whose elements are the squares of the sums of their indices:

```wl
In[5]:=  Array[Plus[##] ^ 2&, {3, 3}]

Out[5]=  {{4, 9, 16}, {9, 16, 25}, {16, 25, 36}}
```

``NestList`` and ``FoldList`` were discussed in ["Applying Functions Repeatedly"](https://reference.wolfram.com/language/tutorial/FunctionalOperations.en.md#23850). Particularly by using them with pure functions, you can construct some very elegant and efficient Wolfram Language programs.

This gives a list of results obtained by successively differentiating $x^n$ with respect to $x$ :

```wl
In[6]:=  NestList[D[#, x]&, x ^ n, 3]

Out[6]=  {x^n, n x^-1 + n, (-1 + n) n x^-2 + n, (-2 + n) (-1 + n) n x^-3 + n}
```

## Selecting Parts of Expressions with Functions

["Manipulating Elements of Lists"](https://reference.wolfram.com/language/tutorial/Lists.en.md#12464) shows how you can pick out elements of lists based on their *positions*. Often, however, you will need to select elements based not on *where* they are, but rather on *what* they are.

``Select[list, f]`` selects elements of ``list`` using the function ``f`` as a criterion. ``Select`` applies ``f`` to each element of ``list`` in turn, and keeps only those for which the result is ``True``.

This selects the elements of the list for which the pure function yields ``True``, i.e., those numerically greater than 4:

```wl
In[1]:=  Select[{2, 15, 1, a, 16, 17}, # > 4&]

Out[1]=  {15, 16, 17}
```

You can use ``Select`` to pick out pieces of any expression, not just elements of a list.

This gives a sum of terms involving ``x``, ``y``, and ``z`` :

```wl
In[2]:=  t = Expand[(x + y + z) ^ 2]

Out[2]=  x^2 + 2 x y + y^2 + 2 x z + 2 y z + z^2
```

You can use ``Select`` to pick out only those terms in the sum that do not involve the symbol ``x`` :

```wl
In[3]:=  Select[t, FreeQ[#, x]&]

Out[3]=  y^2 + 2 y z + z^2
```

|                    |                                                                         |
| ------------------ | ----------------------------------------------------------------------- |
| Select[expr, f]    | select the elements in expr for which the function f gives True         |
| Select[expr, f, n] | select the first n elements in expr for which the function f gives True |

*Selecting pieces of expressions.*

["Putting Constraints on Patterns"](https://reference.wolfram.com/language/tutorial/Patterns.en.md#1615) discusses some "predicates" that are often used as criteria in ``Select``.

This gives the first element which satisfies the criterion you specify:

```wl
In[4]:=  Select[{-1, 3, 10, 12, 14}, # > 3&, 1]

Out[4]=  {10}
```

## Expressions with Heads That Are Not Symbols

In most cases, you want the head ``f`` of a Wolfram Language expression like ``f[x]`` to be a single symbol. There are, however, some important applications of heads that are not symbols.

This expression has ``f[3]`` as a head. You can use heads like this to represent "indexed functions":

```wl
In[1]:= f[3][x, y]

Out[1]= f[3][x, y]
```

You can use any expression as a head. Remember to put in the necessary parentheses:

```wl
In[2]:= (a + b)[x]

Out[2]= (a + b)[x]
```

One case where we have already encountered the use of complicated expressions as heads is in working with pure functions in ["Pure Functions"](https://reference.wolfram.com/language/tutorial/FunctionalOperations.en.md#17469). By giving ``Function[vars, body]`` as the head of an expression, you specify a function of the arguments to be evaluated.

With the head ``Function[x, x ^ 2]``, the value of the expression is the square of the argument:

```wl
In[3]:= Function[x, x ^ 2][a + b]

Out[3]= (a + b)^2
```

There are several constructs in the Wolfram Language which work much like pure functions, but which represent specific kinds of functions, typically numerical ones. In all cases, the basic mechanism involves giving a head which contains complete information about the function you want to use.

|                                   |                                                                         |
| --------------------------------- | ----------------------------------------------------------------------- |
| Function[vars, body][args]        | pure function                                                           |
| InterpolatingFunction[data][args] | approximate numerical function (generated by Interpolation and NDSolve) |
| CompiledFunction[data][args]      | compiled numerical function (generated by Compile)                      |
| LinearSolveFunction[data][vec]    | matrix solution function (generated by LinearSolve)                     |

*Some expressions which have heads that are not symbols.*

``NDSolve`` returns a list of rules that give ``y`` as an ``InterpolatingFunction`` object:

```wl
In[4]:= NDSolve[{y''[x] == y[x], y[0] == y'[0] == 1}, y, {x, 0, 5}]

Out[4]= {{y -> InterpolatingFunction[{{0., 5.}}, <>]}}
```

Here is the ``InterpolatingFunction`` object:

```wl
In[5]:= y /. First[%]

Out[5]= InterpolatingFunction[{{0., 5.}}, <>]
```

You can use the ``InterpolatingFunction`` object as a head to get numerical approximations to values of the function ``y`` :

```wl
In[6]:= %[3.8]

Out[6]= 44.7012
```

Another important use of more complicated expressions as heads is in implementing *functionals* and *functional operators* in mathematics.

As one example, consider the operation of differentiation. As discussed in ["The Representation of Derivatives"](https://reference.wolfram.com/language/tutorial/Calculus.en.md#31655), an expression like ``f'`` represents a *derivative function*, obtained from ``f`` by applying a functional operator to it. In the Wolfram Language, ``f'`` is represented as ``Derivative[1][f]``: the "functional operator" ``Derivative[1]`` is applied to ``f`` to give another function, represented as ``f'``.

This expression has a head which represents the application of the “functional operator” ``Derivative[1]`` to the “function” ``f`` :

```wl
In[7]:= f'[x]//FullForm

Out[7]//FullForm= Derivative[1][f][x]
```

You can replace the head ``f'`` with another head, such as ``fp``. This effectively takes ``fp`` to be a “derivative function” obtained from ``f`` :

```wl
In[8]:= % /. f' -> fp

Out[8]= fp[x]
```

## Working with Operators

You can think of an expression like ``f[x]`` as being formed by applying an operator ``f`` to the expression ``x``. You can think of an expression like ``f[g[x]]`` as the result of *composing* the operators ``f`` and ``g``, and applying the result to ``x``.

|                           |                                         |
| ------------------------- | --------------------------------------- |
| Composition[f, g, …]      | the composition of functions f, g, …    |
| RightComposition[f, g, …] | the composition on the right of f, g, … |
| InverseFunction[f]        | the inverse of a function f             |
| Identity                  | the identity function                   |

*Some functional operations.*

This represents the composition of the functions ``f``, ``g``, and $$h$$ :

```wl
In[1]:= Composition[f, g, h]

Out[1]= Composition[f, g, h]
```

You can manipulate compositions of functions symbolically:

```wl
In[2]:= InverseFunction[Composition[%, q]]

Out[2]= Composition[q^(-1), h^(-1), g^(-1), f^(-1)]
```

The composition is evaluated explicitly when you supply a specific argument:

```wl
In[3]:= %[x]

Out[3]= q^(-1)[h^(-1)[g^(-1)[f^(-1)[x]]]]
```

Composition can be entered using the operator `` @* `` :

```wl
In[4]:= f @* g @* h

Out[4]= Composition[f, g, h]
```

``RightComposition`` composes in the opposite order:

```wl
In[5]:= RightComposition[f, g, h]

Out[5]= Composition[h, g, f]
```

Composition on the right can be entered using the operator `` /* ``

```wl
In[6]:= f /* g /* h

Out[6]= Composition[h, g, f]
```

You can get the sum of two expressions in the Wolfram System just by typing ``x + y``. Sometimes it is also worthwhile to consider performing operations like addition on operators.

You can think of this as containing a sum of two operators ``f`` and ``g`` :

```wl
In[7]:= (f + g)[x]

Out[7]= (f + g)[x]
```

Using ``Through``, you can convert the expression to a more explicit form:

```wl
In[8]:= Through[%, Plus]

Out[8]= f[x] + g[x]
```

This corresponds to the mathematical operator $1+\frac{\partial }{\partial x}$ :

```wl
In[9]:= Identity + (D[#, x]&)

Out[9]= Identity + (Subscript[∂, x]#1&)
```

The Wolfram System does not automatically apply the separate pieces of the operator to an expression:

```wl
In[10]:= %[x ^ 2]

Out[10]= (Identity + (Subscript[∂, x]#1&))[x^2]
```

You can use ``Through`` to apply the operator:

```wl
In[11]:= Through[%, Plus]

Out[11]= 2 x + x^2
```

|                                |                                               |
| ------------------------------ | --------------------------------------------- |
| Identity[expr]                 | the identity function                         |
| Through[p[f1, f2][x], q]       | give p[f1[x], f2[x]] if p is the same as q    |
| Operate[p, f[x]]               | give p[f][x]                                  |
| Operate[p, f[x], n]            | apply p at level n in f                       |
| MapAll[p, expr, Heads -> True] | apply p to all parts of expr, including heads |

*Operations for working with operators.*

This has a complicated expression as a head:

```wl
In[12]:= t = ((1 + a)(1 + b))[x]

Out[12]= ((1 + a) (1 + b))[x]
```

Functions like ``Expand`` do not automatically go inside heads of expressions:

```wl
In[13]:= Expand[%]

Out[13]= ((1 + a) (1 + b))[x]
```

With the ``Heads`` option set to ``True``, ``MapAll`` goes inside heads:

```wl
In[14]:= MapAll[Expand, t, Heads -> True]

Out[14]= (1 + a + b + a b)[x]
```

The replacement operator `` /. `` does go inside heads of expressions:

```wl
In[15]:= t /. a -> 1

Out[15]= (2 (1 + b))[x]
```

You can use ``Operate`` to apply a function specifically to the head of an expression:

```wl
In[16]:= Operate[p, t]

Out[16]= p[(1 + a) (1 + b)][x]
```

## Structural Operations

The Wolfram System contains some powerful primitives for making structural changes to expressions. You can use these primitives both to implement mathematical properties such as associativity and distributivity, and to provide the basis for some succinct and efficient programs.

Here we describe various operations that you can explicitly perform on expressions. ["Attributes"](https://reference.wolfram.com/language/tutorial/EvaluationOfExpressions.en.md#9508) describes how some of these operations can be performed automatically on all expressions with a particular head by assigning appropriate attributes to that head.

You can use the Wolfram System function ``Sort[expr]`` to sort elements not only of lists, but of expressions with any head. In this way, you can implement the mathematical properties of commutativity or symmetry for arbitrary functions.

You can use ``Sort`` to put the arguments of any function into a standard order:

```wl
In[1]:=  Sort[f[c, a, b]]

Out[1]=  f[a, b, c]
```

|                         |                                                                                |
| ----------------------- | ------------------------------------------------------------------------------ |
| Sort[expr]              | sort the elements of a list or other expression into a standard order          |
| Sort[expr, pred]        | sort using the function pred to determine whether pairs are in order           |
| Ordering[expr]          | give the ordering of elements when sorted                                      |
| Ordering[expr, n]       | give the ordering of the first n elements when sorted                          |
| Ordering[expr, n, pred] | use the function pred to determine whether pairs are in order                  |
| OrderedQ[expr]          | give True if the elements of expr are in standard order, and False otherwise   |
| Order[expr1, expr2]     | give 1 if expr1 comes before expr2 in standard order, and -1 if it comes after |

*Sorting into order.*

The second argument to ``Sort`` is a function used to determine whether pairs are in order. This sorts numbers into descending order:

```wl
In[2]:=  Sort[{5, 1, 8, 2}, (#2 < #1)&]

Out[2]=  {8, 5, 2, 1}
```

This sorting criterion puts elements that do not depend on ``x`` before those that do:

```wl
In[3]:=  Sort[{x ^ 2, y, x + y, y - 2}, FreeQ[#1, x]&]

Out[3]=  {y, -2 + y, x + y, x^2}
```

|                     |                                                             |
| ------------------- | ----------------------------------------------------------- |
| Flatten[expr]       | flatten out all nested functions with the same head as expr |
| Flatten[expr, n]    | flatten at most n levels of nesting                         |
| Flatten[expr, n, h] | flatten functions with head h                               |
| FlattenAt[expr, i]  | flatten only the i$$^{\text{th}}$$ element of expr          |

*Flattening out expressions.*

``Flatten`` removes nested occurrences of a function:

```wl
In[4]:=  Flatten[f[a, f[b, c], f[f[d]]]]

Out[4]=  f[a, b, c, d]
```

You can use ``Flatten`` to "splice" sequences of elements into lists or other expressions:

```wl
In[5]:=  Flatten[{a, f[b, c], f[a, b, d]}, 1, f]

Out[5]=  {a, b, c, a, b, d}
```

You can use ``Flatten`` to implement the mathematical property of associativity. The function ``Distribute`` allows you to implement properties such as distributivity and linearity.

|                                |                                                                  |
| ------------------------------ | ---------------------------------------------------------------- |
| Distribute[f[a + b + …, …]]    | distribute f over sums to give f[a, …] + f[b, …] + …             |
| Distribute[f[args], g]         | distribute f over any arguments which have head g                |
| Distribute[expr, g, f]         | distribute only when the head is f                               |
| Distribute[expr, g, f, gp, fp] | distribute f over g, replacing them with fp and gp, respectively |

*Applying distributive laws.*

This "distributes" ``f`` over ``a + b`` :

```wl
In[6]:=  Distribute[f[a + b]]

Out[6]=  f[a] + f[b]
```

Here is a more complicated example:

```wl
In[7]:=  Distribute[f[a + b, c + d]]

Out[7]=  f[a, c] + f[a, d] + f[b, c] + f[b, d]
```

In general, if ``f`` is distributive over ``Plus``, then an expression like ``f[a + b]`` can be "expanded" to give ``f[a] + f[b]``. The function ``Expand`` does this kind of expansion for standard algebraic operators such as ``Times``. ``Distribute`` allows you to perform the same kind of expansion for arbitrary operators.

``Expand`` uses the distributivity of ``Times`` over ``Plus`` to perform algebraic expansions:

```wl
In[8]:=  Expand[(a + b) (c + d)]

Out[8]=  a c + b c + a d + b d
```

This applies distributivity over lists, rather than sums. The result contains all possible pairs of arguments:

```wl
In[9]:=  Distribute[f[{a, b}, {c, d}], List]

Out[9]=  {f[a, c], f[a, d], f[b, c], f[b, d]}
```

This distributes over lists, but does so only if the head of the whole expression is ``f`` :

```wl
In[10]:=  Distribute[f[{a, b}, {c, d}], List, f]

Out[10]=  {f[a, c], f[a, d], f[b, c], f[b, d]}
```

This distributes over lists, making sure that the head of the whole expression is ``f``. In the result, it uses ``gp`` in place of ``List``, and ``fp`` in place of ``f`` :

```wl
In[11]:=  Distribute[f[{a, b}, {c, d}], List, f, gp, fp]

Out[11]=  gp[fp[a, c], fp[a, d], fp[b, c], fp[b, d]]
```

Related to ``Distribute`` is the function ``Thread``. What ``Thread`` effectively does is to apply a function in parallel to all the elements of a list or other expression.

|                               |                                                    |
| ----------------------------- | -------------------------------------------------- |
| Thread[f[{a1, a2}, {b1, b2}]] | thread f over lists to give {f[a1, b1], f[a2, b2]} |
| Thread[f[args], g]            | thread f over objects with head g in args          |

*Functions for threading expressions.*

Here is a function whose arguments are lists:

```wl
In[12]:=  f[{a1, a2}, {b1, b2}]

Out[12]=  f[{a1, a2}, {b1, b2}]
```

``Thread`` applies the function "in parallel" to each element of the lists:

```wl
In[13]:=  Thread[%]

Out[13]=  {f[a1, b1], f[a2, b2]}
```

Arguments that are not lists get repeated:

```wl
In[14]:=  Thread[f[{a1, a2}, {b1, b2}, c, d]]

Out[14]=  {f[a1, b1, c, d], f[a2, b2, c, d]}
```

As mentioned in ["Collecting Objects Together"](https://reference.wolfram.com/language/tutorial/Lists.en.md#15568), and discussed in more detail in ["Attributes"](https://reference.wolfram.com/language/tutorial/EvaluationOfExpressions.en.md#9508), many built‐in Wolfram System functions have the property of being "listable", so that they are automatically threaded over any lists that appear as arguments.

Built‐in mathematical functions such as ``Log`` are listable, so that they are automatically threaded over lists:

```wl
In[15]:=  Log[{a, b, c}]

Out[15]=  {Log[a], Log[b], Log[c]}
```

``Log`` is, however, not automatically threaded over equations:

```wl
In[16]:=  Log[x == y]

Out[16]=  Log[x == y]
```

You can use ``Thread`` to get functions applied to both sides of an equation:

```wl
In[17]:=  Thread[%, Equal]

Out[17]=  Log[x] == Log[y]
```

|                           |                           |
| ------------------------- | ------------------------- |
| Outer[f, list1, list2]    | generalized outer product |
| Inner[f, list1, list2, g] | generalized inner product |

*Generalized outer and inner products.*

``Outer[f, list1, list2]`` takes all possible combinations of elements from ``list1`` and ``list2``, and combines them with ``f``. ``Outer`` can be viewed as a generalization of a Cartesian product for tensors, as discussed in ["Tensors"](https://reference.wolfram.com/language/tutorial/LinearAlgebra.en.md#20229).

``Outer`` forms all possible combinations of elements, and applies ``f`` to them:

```wl
In[18]:=  Outer[f, {a, b}, {1, 2, 3}]

Out[18]=  {{f[a, 1], f[a, 2], f[a, 3]}, {f[b, 1], f[b, 2], f[b, 3]}}
```

Here ``Outer`` produces a lower‐triangular Boolean matrix:

```wl
In[19]:=  Outer[Greater, {1, 2, 3}, {1, 2, 3}]

Out[19]=  {{False, False, False}, {True, False, False}, {True, True, False}}
```

You can use ``Outer`` on any sequence of expressions with the same head:

```wl
In[20]:=  Outer[g, f[a, b], f[c, d]]

Out[20]=  f[f[g[a, c], g[a, d]], f[g[b, c], g[b, d]]]
```

``Outer``, like ``Distribute``, constructs all possible combinations of elements. On the other hand, ``Inner``, like ``Thread``, constructs only combinations of elements that have corresponding positions in the expressions it acts on.

Here is a structure built by ``Inner`` :

```wl
In[21]:=  Inner[f, {a, b}, {c, d}, g]

Out[21]=  g[f[a, c], f[b, d]]
```

``Inner`` is a generalization of ``Dot`` :

```wl
In[22]:=  Inner[Times, {a, b}, {c, d}, Plus]

Out[22]=  a c + b d
```

## Sequences

The function ``Flatten`` allows you to explicitly flatten out all sublists:

```wl
In[1]:=  Flatten[{a, {b, c}, {d, e}}]

Out[1]=  {a, b, c, d, e}
```

``FlattenAt`` lets you specify at what positions you want sublists flattened:

```wl
In[2]:=  FlattenAt[{a, {b, c}, {d, e}}, 2]

Out[2]=  {a, b, c, {d, e}}
```

``Sequence`` objects automatically get spliced in, and do not require any explicit flattening:

```wl
In[3]:=  {a, Sequence[b, c], Sequence[d, e]}

Out[3]=  {a, b, c, d, e}
```

|                     |                                                                              |
| ------------------- | ---------------------------------------------------------------------------- |
| Sequence[e1, e2, …] | a sequence of arguments that will automatically be spliced into any function |

*Representing sequences of arguments in functions.*

``Sequence`` works in any function:

```wl
In[4]:=  f[Sequence[a, b], c]

Out[4]=  f[a, b, c]
```

This includes functions with special input forms:

```wl
In[5]:=  a == Sequence[b, c]

Out[5]=  a == b == c
```

Here is a common way that ``Sequence`` is used:

```wl
In[6]:=  {a, b, f[x, y], g[w], f[z, y]} /. f -> Sequence

Out[6]=  {a, b, x, y, g[w], z, y}
```

## Related Guides

* [Functional Programming](https://reference.wolfram.com/language/guide/FunctionalProgramming.en.md)