# 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" 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.

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[expr_{1},expr_{2}] | give 1 if expr_{1} comes before expr_{2} in standard order, and -1 if it comes after |

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 element of expr |

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 |

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.

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[{a_{1},a_{2}},{b_{1},b_{2}}]] | thread f over lists to give {f[a_{1},b_{1}],f[a_{2},b_{2}]} |

Thread[f[args],g] | thread f over objects with head g in args |

Functions for threading expressions.

As mentioned in "Collecting Objects Together", and discussed in more detail in "Attributes", 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.

Outer[f,list_{1},list_{2}] | generalized outer product |

Inner[f,list_{1},list_{2},g] | generalized inner product |

Generalized outer and inner products.

Outer[f,list_{1},list_{2}] takes all possible combinations of elements from list_{1} and list_{2}, and combines them with f. Outer can be viewed as a generalization of a Cartesian product for tensors, as discussed in "Tensors".

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.