You may have noticed that there are two different ways to make assignments in the Wolfram Language: lhs=rhs and lhs:=rhs. The basic difference between these forms is when the expression rhs is evaluated. lhs=rhs is an immediate assignment, in which rhs is evaluated at the time when the assignment is made. lhs:=rhs, on the other hand, is a delayed assignment, in which rhs is not evaluated when the assignment is made, but is instead evaluated each time the value of lhs is requested.
|lhs=rhs (immediate assignment)||rhs is evaluated when the assignment is made|
|lhs:=rhs (delayed assignment)||rhs is evaluated each time the value of lhs is requested|
One rule of thumb is the following. If you think of an assignment as giving the final "value" of an expression, use the = operator. If instead you think of the assignment as specifying a "command" for finding the value, use the := operator. If in doubt, it is usually better to use the := operator than the = one.
|lhs=rhs||rhs is intended to be the "final value" of lhs (e.g. f[x_]=1-x^2)|
|lhs:=rhs||rhs gives a "command" or "program" to be executed whenever you ask for the value of lhs (e.g. f[x_]:=Expand[1-x^2])|
Although := is probably used more often than = in defining functions, there is one important case in which you must use = to define a function. If you do a calculation, and get an answer in terms of a symbolic parameter , you often want to go on and find results for various specific values of . One way to do this is to use the /. operator to apply appropriate rules for in each case. It is usually more convenient, however, to use = to define a function whose argument is .
An important point to notice in the example above is that there is nothing special about the name x that appears in the x_ pattern. It is just a symbol, indistinguishable from an x that appears in any other expression.
You can use = and := not only to define functions, but also to assign values to variables. If you type x=value, then value is immediately evaluated, and the result is assigned to x. On the other hand, if you type x:=value, then value is not immediately evaluated. Instead, it is maintained in an unevaluated form, and is evaluated afresh each time is used.
You can use delayed assignments such as t:=rhs to set up variables whose values you can find in a variety of different "environments". Every time you ask for Null, the expression rhs is evaluated using the current values of the objects on which it depends.
In the example above, the symbol a acts as a "global variable", whose value affects the value of t. When you have a large number of parameters, many of which change only occasionally, you may find this kind of setup convenient. However, you should realize that implicit or hidden dependence of one variable on others can often become quite confusing. When possible, you should make all dependencies explicit, by defining functions which take all necessary parameters as arguments.