OwnValues, Set, and SetDelayed
Set and SetDelayed
Both Set
and SetDelayed
work by setting definitions on a symbol. What this means in practice is that Set
and SetDelayed
add replacement patterns to one of the ⋆Values
lists of the symbol. The lists can be OwnValues
, DownValues
, UpValues
or SubValues
. There are also NValues
and FormatValues
, but these are assigned via alternate interfaces and do not have much effect on real programming.
OwnValues
OwnValues
are the most fundamental type of ⋆Values
. These represent things like the following:
a = 10;
a := 20;
We can then query the OwnValues
OwnValues@a
(*Out:*)
{HoldPattern[a] :> 20}
We can even edit the OwnValues
manually if we know what we’re doing:
OwnValues[a] = Prepend[OwnValues[a], HoldPattern[a] :> 50]
(*Out:*)
{HoldPattern[a] :> 50, HoldPattern[a] :> 20}
a
(*Out:*)
50
Something interesting happens, though, if you set more values on a via SetDelayed
:
a := 100
OwnValues@a
(*Out:*)
{HoldPattern[a] :> 100, HoldPattern[a] :> 20}
a := 32
OwnValues@a
(*Out:*)
{HoldPattern[a] :> 32, HoldPattern[a] :> 20}
Only the first entry is changed. This behavior could be used with something like the following to cache symbol values:
setValue[s_Symbol,
v_] := (OwnValues[s] =
Prepend[OwnValues[s], HoldPattern[s] :> v]);
resetValue[s_Symbol] := (OwnValues[s] = Rest@OwnValues[s]);
SetAttributes[setValue, HoldFirst];
SetAttributes[resetValue, HoldFirst]
setValue[a, 10];
a
(*Out:*)
10
setValue[a, 20];
a
(*Out:*)
20
resetValue[a];
a
(*Out:*)
10
Notice that using a plain Set
erases these changes:
a = 10
(*Out:*)
10
OwnValues@a
(*Out:*)
{HoldPattern[a] :> 10}
Even if now we add more values Set
will erase them all:
OwnValues[a] =
Join[ConstantArray[HoldPattern[a] :> 25, 10], OwnValues@a]
(*Out:*)
{HoldPattern[a] :> 25, HoldPattern[a] :> 25, HoldPattern[a] :> 25,
HoldPattern[a] :> 25, HoldPattern[a] :> 25, HoldPattern[a] :> 25,
HoldPattern[a] :> 25, HoldPattern[a] :> 25, HoldPattern[a] :> 25,
HoldPattern[a] :> 25, HoldPattern[a] :> 10}
a = 10
(*Out:*)
10
OwnValues@a
(*Out:*)
{HoldPattern[a] :> 10}