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}

results matching ""

    No results matching ""