Functions
Functions are common to all programming languages. They work exactly like the name suggests. A single input or set of inputs is mapped to a single output.
In Mathematica, functions are defined using variables followed by an underscore square brackets and can be defined with either =
or :=
, which has the same meaning as with variables.
=
uses the immediate values of the right hand side while :=
recalculates these when called for.
The :=
definition works most similarly to standard programming languages and is the definition I would suggest using by default
Here we'll define a simple function to add two primes using :=
primeSum[n1_, n2_] := Prime[n1] + Prime[n2]
primeSum[1, 10]
(*Out:*)
31
The same works with plain =
primeSum[n1_, n2_] = Prime[n1] + Prime[n2]
(*Out:*)
Prime[n1] + Prime[n2]
primeSum[1, 10]
(*Out:*)
31
Differences between = and :=
Let’s write a more complex function that moves a position around randomly. This position could be the position of an atom, say as hydrogen. Let’s start it out at the origin.
hydrogenPosition = {0, 0, 0};
Now we’ll define a function to move our hydrogen around randomly and return where it is now.
moveOurH[] :=
Row@{
"H is at:",
hydrogenPosition +=
{
RandomReal[{-1, 1}],
RandomReal[{-1, 1}],
RandomReal[{-1, 1}]
}
}
moveOurH[]
(*Out:*)
Row[{"H is at:", {0.524521, 0.626446, -0.705801} }]
moveOurH[]
(*Out:*)
Row[{"H is at:", {0.239477, 0.598285, -1.29094} }]
moveOurH[]
(*Out:*)
Row[{"H is at:", {-0.632497, 0.50078, -0.826784} }]
Now let’s try to do the same, but using =
hydrogenPosition = {0, 0, 0};
moveOurH[] =
Row@{
"H is at:",
hydrogenPosition +=
{
RandomReal[{-1, 1}],
RandomReal[{-1, 1}],
RandomReal[{-1, 1}]
}
};
moveOurH[]
(*Out:*)
Row[{"H is at:", {-0.279658, -0.455241, -0.0753173} }]
moveOurH[]
(*Out:*)
Row[{"H is at:", {-0.279658, -0.455241, -0.0753173} }]
moveOurH[]
(*Out:*)
Row[{"H is at:", {-0.279658, -0.455241, -0.0753173} }]
You’ll notice our position doesn’t change. That’s because the right hand side was evaluated as the function was defined.
Note that this is not always a bug. Sometimes this can be a feature as there are instances where having most values set is useful.
Function
There is also a special type called Function which is defined as follows:
Function[{var1, var2, var3, ..., varn}, code]
This is useful primarily in complicated code when a simple function needs to be used just once or twice and it is not worth defining a full function to do this.
This form of function can also be defined as follows:
(code &)
where var1,var2,var3,...,varn are replaced by #1,#2,...,#n in the code. For example:
Function[
{a, b, c},
Grid@{
{"a is:", a},
{"b is:", b},
{"c is:", c}
}
]
could be written as:
(Grid@{
{"a is:", #1},
{"b is:", #2},
{"c is:", #3}
} &)
And to see that they are in fact the same function:
Function[
{a, b, c},
Grid@{
{"a is:", a},
{"b is:", b},
{"c is:", c}
}
][1, 2, 3]
(*Out:*)
"a is:" | 1 |
"b is:" | 2 |
"c is:" | 3 |
(Grid@{
{"a is:", #1},
{"b is:", #2},
{"c is:", #3}
} &)[1, 2, 3]
(*Out:*)
"a is:" | 1 |
"b is:" | 2 |
"c is:" | 3 |
In Mathematica these are known as pure functions, to distinguish them from functions defined the way we’ve done before.