Everything Is an Expression
The Wolfram Language handles many different kinds of things: mathematical formulas, lists, and graphics, to name a few. Although they often look very different, the Wolfram Language represents all of these things in one uniform way. They are all expressions.
A prototypical example of a Wolfram Language expression is f[x,y]. You might use f[x,y] to represent a mathematical function . The function is named f, and it has two arguments, x and y.
You do not always have to write expressions in the form f[x,y,]. For example, x+y is also an expression. When you type in x+y, the Wolfram Language converts it to the standard form Plus[x,y]. Then, when it prints it out again, it gives it as x+y.
The same is true of other "operators", such as ^ (Power) and / (Divide).
In fact, everything you type into the Wolfram Language is treated as an expression.
Some examples of Wolfram Language expressions.
You can see the full form of any expression by using FullForm[expr].
Here is an expression:
This is the full form of the expression:
Here is another expression:
Its full form has several nested pieces:
The object f in an expression f[x,y,] is known as the head of the expression. You can extract it using Head[expr]. Particularly when you write programs in the Wolfram Language, you will often want to test the head of an expression to find out what kind of thing the expression is.
Head gives the "function name" f:
Here Head gives the name of the "operator":
Everything has a head:
Numbers also have heads:
You can distinguish different kinds of numbers by their heads:
give the head of an expression: the f in f[x,y]
display an expression in the full form used by the Wolfram Language
Functions for manipulating expressions.
The Meaning of Expressions
The notion of expressions is a crucial unifying principle in the Wolfram System. It is the fact that every object in the Wolfram System has the same underlying structure that makes it possible for the Wolfram System to cover so many areas with a comparatively small number of basic operations.
Although all expressions have the same basic structure, there are many different ways that expressions can be used. Here are a few of the interpretations you can give to the parts of an expression.
meaning of f
meaning of x,y,
arguments or parameters
arguments or parameters
Object type
Some interpretations of parts of expressions.
Expressions in the Wolfram System are often used to specify operations. So, for example, typing in 2+3 causes 2 and 3 to be added together, while Factor[x^6-1] performs factorization.
Perhaps an even more important use of expressions in the Wolfram System, however, is to maintain a structure, which can then be acted on by other functions. An expression like {a,b,c} does not specify an operation. It merely maintains a list structure, which contains a collection of three elements. Other functions, such as Reverse or Dot, can act on this structure.
The full form of the expression {a,b,c} is List[a,b,c]. The head List performs no operations. Instead, its purpose is to serve as a "tag" to specify the "type" of the structure.
You can use expressions in the Wolfram System to create your own structures. For example, you might want to represent points in threedimensional space, specified by three coordinates. You could give each point as point[x,y,z]. The "function" point again performs no operation. It serves merely to collect the three coordinates together, and to label the resulting object as a point.
You can think of expressions like point[x,y,z] as being "packets of data", tagged with a particular head. Even though all expressions have the same basic structure, you can distinguish different "types" of expressions by giving them different heads. You can then set up transformation rules and programs which treat different types of expressions in different ways.
Special Ways to Input Expressions
The Wolfram Language allows you to use special notation for many common operators. For example, although internally the Wolfram System represents a sum of two terms as Plus[x,y], you can enter this expression in the much more convenient form x+y.
The Wolfram Language has a definite grammar that specifies how your input should be converted to internal form. One aspect of the grammar is that it specifies how pieces of your input should be grouped. For example, if you enter an expression such as a+b^c, the Wolfram Language grammar specifies that this should be considered, following standard mathematical notation, as a+(b^c) rather than (a+b)^c. The Wolfram Language chooses this grouping because it treats the operator ^ as having a higher precedence than +. In general, the arguments of operators with higher precedence are grouped before those of operators with lower precedence.
You should realize that absolutely every special input form in the Wolfram Language is assigned a definite precedence. This includes not only the traditional mathematical operators, but also forms such as ->, := or the semicolons used to separate expressions in a Wolfram Language program.
The table in "Operator Input Forms" gives all the operators of the Wolfram Language in order of decreasing precedence. The precedence is arranged, where possible, to follow standard mathematical usage, and to minimize the number of parentheses that are usually needed.
You will find, for example, that relational operators such as < have lower precedence than arithmetic operators such as +. This means that you can write expressions such as x+y>7 without using parentheses.
There are nevertheless many cases where you do have to use parentheses. For example, since ; has a lower precedence than =, you need to use parentheses to write x=(a;b). The Wolfram System interprets the expression x=a;b as (x=a);b. In general, it can never hurt to include extra parentheses, but it can cause a great deal of trouble if you leave parentheses out, and the Wolfram System interprets your input in a way you do not expect.
standard form for f[x,y]
prefix form for f[x]
postfix form for f[x]
infix form for f[x,y]
Four ways to write expressions in the Wolfram Language.
There are several common types of operators in the Wolfram Language. The + in x+y is an "infix" operator. The - in -p is a "prefix" operator. Even when you enter an expression such as f[x,y,] the Wolfram Language allows you to do it in ways that mimic infix, prefix and postfix forms.
This "postfix form" is exactly equivalent to f[x+y]:
You will often want to add functions like N as "afterthoughts", and give them in postfix form:
It is sometimes easier to understand what a function is doing when you write it in infix form:
You should notice that // has very low precedence. If you put //f at the end of any expression containing arithmetic or logical operators, the f is applied to the whole expression. So, for example, x+y//f means f[x+y], not x+f[y].
The prefix form @ has a much higher precedence. f@x+y is equivalent to f[x]+y, not f[x+y]. You can write f[x+y] in prefix form as f@(x+y).
Parts of Expressions
Since lists are just a particular kind of expression, it will come as no surprise that you can refer to parts of any expression much as you refer to parts of a list.
This gets the second element in the list {a,b,c}:
You can use the same method to get the second element in the sum x+y+z:
This gives the last element in the sum:
Part 0 is the head:
You can refer to parts of an expression such as f[g[a],g[b]] just as you refer to parts of nested lists.
This is part 1:
This is part {1,1}:
This extracts part {2,1} of the expression 1+x^2:
To see what part is {2,1}, you can look at the full form of the expression:
You should realize that the assignment of indices to parts of expressions is done on the basis of the internal Wolfram Language forms of the expression, as shown by FullForm. These forms do not always correspond directly with what you see printed out. This is particularly true for algebraic expressions, where the Wolfram Language uses a standard internal form, but prints the expressions in special ways.
Here is the internal form of x/y:
It is the internal form that is used in specifying parts:
You can manipulate parts of expressions just as you manipulate parts of lists.
This replaces the third part of a+b+c+d by x^2. Note that the sum is automatically rearranged when the replacement is done:
Here is an expression:
This is the full form of t:
This resets a part of the expression t:
Now the form of t has been changed:
the th part of expr
a combination of parts of an expression
parts through of an expression
replace the th part of expr by elem
Functions for manipulating parts of expressions.
"Manipulating Elements of Lists" discusses how you can use lists of indices to pick out several elements of a list at a time. You can use the same procedure to pick out several parts in an expression at a time.
This picks out elements 2 and 4 in the list, and gives a list of these elements:
This picks out parts 2 and 4 of the sum, and gives a sum of these elements:
Any part in an expression can be viewed as being an argument of some function. When you pick out several parts by giving a list of indices, the parts are combined using the same function as in the expression.
This picks out parts 2 through 4 of the list:
Manipulating Expressions like Lists
You can use most of the list operations discussed in "Lists" on any kind of Wolfram Language expression. By using these operations, you can manipulate the structure of expressions in many ways.
Here is an expression that corresponds to a sum of terms:
Take[t,2] takes the first two elements from t, just as if t were a list:
Length gives the number of elements in t:
You can use FreeQ[expr,form] to test whether form appears nowhere in expr:
This gives a list of the positions at which x appears in t:
You should remember that all functions which manipulate the structure of expressions act on the internal forms of these expressions. You can see these forms using FullForm[expr]. They may not be what you would expect from the printed versions of the expressions.
Here is a function with four arguments:
You can add an argument using Append:
This reverses the arguments:
There are a few extra functions that can be used with expressions, as discussed in "Structural Operations".
Expressions as Trees
Here is an expression in full form:
TreeForm prints out expressions to show their "tree" structure:
You can think of any Wolfram Language expression as a tree. In the expression above, the top node in the tree consists of a Plus. From this node come two "branches", x^3 and (1+x)^2. From the x^3 node, there are then two branches, x and 3, which can be viewed as "leaves" of the tree.
This matrix is a simple tree with just two levels:
Here is a more complicated expression:
The tree for this expression has several levels:
The indices that label each part of an expression have a simple interpretation in terms of trees. Descending from the top node of the tree, each index specifies which branch to take in order to reach the part you want.
Levels in Expressions
The Part function allows you to access specific parts of Wolfram Language expressions. But particularly when your expressions have fairly uniform structure, it is often convenient to be able to refer to a whole collection of parts at the same time.
Levels provide a general way of specifying collections of parts in Wolfram Language expressions. Many Wolfram Language functions allow you to specify the levels in an expression on which they should act.
Here is a simple expression, displayed in tree form:
This searches for x in the expression t down to level 1. It finds only one occurrence:
This searches down to level 2. Now it finds both occurrences of x:
This searches only at level 2. It finds just one occurrence of x:
give the positions at which form occurs in expr down to level n
give the positions exactly at level n
Controlling Position using levels.
You can think of levels in expressions in terms of trees. The level of a particular part in an expression is simply the distance down the tree at which that part appears, with the top of the tree considered as level 0.
It is equivalent to say that the parts which appear at level n are those that can be specified by a sequence of exactly n indices.
levels 1 through n
all levels (except 0)
level n only
levels n1 through n2
include heads
exclude heads
Level specifications.
Here is an expression, displayed in tree form:
This searches for a at levels from 2 downward:
This shows where f appears other than in the head of an expression:
This includes occurrences of f in heads of expressions:
a list of the parts of expr at the levels specified by lev
the total number of levels in expr
Testing and extracting levels.
This gives a list of all parts of u that occur down to level 2:
Here are the parts specifically at level 2:
When you have got the hang of ordinary levels, you can try thinking about negative levels. Negative levels label parts of expressions starting at the bottom of the tree. Level -1 contains all the leaves of the tree: objects like symbols and numbers.
This shows the parts of u at level -1:
You can think of expressions as having a "depth", as shown by TreeForm. In general, level -n in an expression is defined to consist of all subexpressions whose depth is n.
The depth of g[a] is 2:
The parts of u at level -2 are those that have depth exactly 2: