### Preamble

In addition to the differences between these global rules reflected in the patterns for which assignment operators put the global rule into one or another `...Value`

, there is another, and IMO,no less important difference, and that is in how these rules are used in the evaluation sequence.

### Evaluation: OwnValues

The `OwnValues`

represent symbols themselves, and therefore they are applied when symbols are evaluated. If these symbols are atomic elements inside some expression, and evaluation comes to them, they are (normally) replaced with the r.h.s. of their `OwnValues`

. The more interesting situation is when the symbols are heads of some normal expressions. In this case, since heads are evaluated very early in the evaluation sequence, these symbols are also replaced with what their `OwnValues`

instruct, but now as heads.

This has several consequences. Here is one example:

```
In[75]:=
ClearAll[f,h];
SetAttributes[f,{Orderless,SequenceHold}];
f=h;
f[5,4,3,2,1]
Out[78]= h[5,4,3,2,1]
In[79]:= f[Sequence[1,2,3]]
Out[79]= h[1,2,3]
```

As you can see, none of the Attributes assigned to `f`

actually had a chance to play, since `f`

was replaced by `h`

before the attributes were even considered by the evaluator. The same will happen when we add some definitions (as `DownValues`

, `UpValues`

or `SubValues`

):

```
In[106]:=
g[x_]:=x^2;
g=h;
g[5]
Out[108]= h[5]
```

Once again, these definitions had no chance to execute.

These cases may seem contrived, and indeed they do not happen very often as results of a deliberate coding, but they can quite often happen due to a mistake, and then are hard to debug. One very relevant discussion is here. To complete this part, let me mention another very insidious case. Let us just take the last example and reverse the order in which we were creating definitions:

```
In[109]:= ClearAll[g,h]
g=h;
g[x_]:=x^2;
g[5]
Out[112]= 25
```

Somewhat miraculously, the code worked, seemingly contradicting my previous statements. But let us look closer:

```
?g
Global`g
g=h
```

is all right, but this

```
?h
Global`h
h[x_]:=x^2
```

may be a surprise. This is an example of *evaluation during assigments*. A more complete discussion can be found e.g. here. This is just another pitfall to watch out for.

### Evaluation: DownValues vs SubValues

It is useful to know that `DownValues`

are applied before `SubValues`

. Therefore, here we get:

```
ClearAll[f];
f[1][x_]:=x^2;
f[n_]:=n;
In[118]:= f[1][3]
Out[118]= 1[3]
```

Had I reversed the order of definitions, and we'd have got this:

```
ClearAll[f];
f[n_]:=n;
f[1][x_]:=x^2;
SetDelayed::write: Tag Integer in 1[x_] is Protected. >>
```

This is another case of evaluation during an assigment: the first definition for `f`

evaluated inside `SetDelayed`

when we attempted to create the second one.

Another important difference: functions defined via `DownValues`

can hold all their arguments if needed, through the `HoldAll`

or `HoldAllComplete`

attributes. Functions defined with `SubValues`

, however, can only normally hold the "innermost" group of arguments:

```
In[125]:= ClearAll[g];
SetAttributes[g,HoldAll];
g[x_][y_]:={Head[Unevaluated[x]],Head[Unevaluated[y]]}
In[128]:= g[Print[1]][Print[2]]
During evaluation of In[128]:= 2
Out[128]= {Print,Symbol}
```

The only workaround I am aware of, when such construct is needed, is this:

```
In[129]:= ClearAll[g];
SetAttributes[g,HoldAll];
g[x_]:=Function[y,{Head[Unevaluated[x]],Head[Unevaluated[y]]},HoldAll]
In[132]:= g[Print[1]][Print[2]]
Out[132]= {Print,Print}
```

Similar situation holds for some other attributes, e.g. `Listable`

. This topic is discussed in more detail e.g. here

### DownValues vs UpValues: System-wide changes vs. locality

There are several important ways in which `UpValues`

are different from `DownValues`

. One very important aspect is that they allow you to "softly" overload some system functions only on certain symbols. The importance of this can not be emphasized enough - this makes the effect of your code local, and drastically reduces the chances that your code can globally interact and affect some other part of the system or other piece of user-defined code, unlike when you `Unprotect`

system symbols and add some `DownValues`

to them.

In addition to being safe and local, such redefinitions may also be quite general, if one uses constructs like `yourSymbol/:f_[_yourSymbol,rest___]:=...`

. These should be used with care, but can sometimes give very concise and simple solutions. Here is one example where one code can be used to "overload" several system functions at once, giving them additional non-trivial functionality.

### DownValues vs UpValues: Order of evaluation

The next point is evaluation. The common statement you can encounter is that "`UpValues`

are applied before `DownValues`

". This must be clarified: for `f[g[args]]`

it means that `UpValues`

for `g`

are applied before `DownValues`

for `f`

, provided that the evaluation process already went all they way "down" to innermost parts, and then went back "up". In particular, it does not mean that `UpValues`

for `g`

will be applied before `DownValues`

for `g`

- if `g[args]`

can evaluate inside `f`

because `g`

has appropriate `DownValues`

, it will (unless f has one of the `Hold`

-attributes), and the presence of `UpValues`

won't prevent that, because (for standard evaluation), evaluation of `g[args]`

happens before the evaluation of `f[result-of-evaluation-of g[args]]`

. For example, here:

```
In[133]:=
ClearAll[f, g];
f[x_] := x^2;
g /: f[g[x_]] := Sin[g[x]];
g[x_] := Cos[x];
In[137]:= f[g[y]]
Out[137]= Cos[y]^2
```

The `UpValues`

for `g`

had no chance to apply, since `g[y]`

is transformed into `Cos[y]`

at the previous evaluation step. The situation would be different for non-standard evaluation - either if we give `f`

attributes `HoldAll`

or `HoldFirst`

, or if we wrap `g[y]`

in `Unevaluated`

- in both cases we give the evaluator the instruction to skip the evaluation of `g[y]`

:

```
In[138]:= f[Unevaluated[g[y]]]
Out[138]= Sin[Cos[y]]
```

### DownValues vs UpValues: Hold-attributes

This one is related to the previous point: one should be aware that search for `UpValues`

is performed even inside heads with `Hold`

- attributes, and therefore, `UpValue`

-based definitions may evaluate even when similarly-looking `DownValue`

- based ones won't. Example:

```
In[139]:= ClearAll[f,ff];
f[x_]:=Print["Evaluated"];
ff/:h_[ff[x_]]:=Print["Evaluated"];
In[142]:= Hold[f[1]]
Out[142]= Hold[f[1]]
In[143]:= Hold[ff[1]]
During evaluation of In[143]:= Evaluated
```

If one wants to absolutely prevent the search for `UpValues`

, one should give a function the `HoldAllComplete`

attribute. For example:

```
In[144]:= {HoldComplete[f[1]],HoldComplete[ff[1]]}
Out[144]= {HoldComplete[f[1]],HoldComplete[ff[1]]}
```

### Summary

I tried to outline and illustrate several technical points which pop up quite frequently in practice and can be frustrating at first. My main message is that a huge difference between different kinds of rules is induced by the way they are used in the main evaluation sequence. This difference may not be immediately apparent, but it affects all aspects of how these rules are used in practice.

2Just for completeness, there's also

`FormatValues`

and`NValues`

, (and less importantly:`DefaultValues`

,`DynamicModuleValues`

and`SingularValues`

) – Simon – 2012-01-18T04:39:21.407This link is interesting regarding many type of values http://www.verbeia.com/mathematica/tips/HTMLLinks/Tricks_Misc_4.html

– faysou – 2012-01-18T09:57:45.4237

@Simon

– Szabolcs – 2012-01-18T16:20:44.813`SingularValues`

is a function that calculates the singular values for a matrix.`DynamicModuleValues`

is an option name. They are not in this category.4

@Simon You can see everything that's

– Szabolcs – 2012-01-18T16:21:26.233associated with symbolsby evaluating something like`Language`FullDefinition[x]`

. The rest are`NValues`

, which can be set as`N[x] = 1.0`

,`DefaultValues`

storing default argument values,`FormatValues`

(please see`Format`

which is also assignable),`Messages`

(self explanatory) and`Attributes`

(self explanatory).@Simon: also,

`SingularValues[]`

is deprecated. – J. M.'s ennui – 2012-01-21T02:10:05.630