11
$\begingroup$

The DownValues, UpValues, and OwnValues functions are all plural. In general, a Symbol may have multiple DownValues or UpValues. For example:

f[x_]:= x^2
f[x_, y_]:= x^2 + y^2
DownValues[f]
{HoldPattern[f[x_]]:>x^2,HoldPattern[f[x_,y_]]:>x^2+y^2}

Can a Symbol have more than one OwnValue?

$\endgroup$
  • $\begingroup$ If a symbol had more than one OwnValue, what would you expect to see as the result of evaluating it? $\endgroup$ – John Doty Jul 5 '18 at 22:14
  • 1
    $\begingroup$ Oh, I have no idea. But Mathematica has no problem with assigning an OwnValue that makes a DownValue inaccessible, so I see no reason it would have a problem with an inaccessible OwnValue. $\endgroup$ – Robert Jacobson Jul 5 '18 at 22:31
7
$\begingroup$

Yes, it can, but only the first matching rule gets applied:

ClearAll[x];
OwnValues[x] = {x :> 1, x :> 2};
OwnValues[x]
Definition[x]
x

{HoldPattern[x] :> 1, HoldPattern[x] :> 2}

x : = 1

x : = 2

1

Compare also to

ClearAll[x];
OwnValues[x] = {x -> 1, x -> 2};
OwnValues[x]
Definition[x]
x

{HoldPattern[x] :> 1, HoldPattern[x] :> 2}

x = 1

x = 2

1

In a comment, Leonid brought up conditional rules in order to point out that it is really the first matching rule that applies. Here is an example that shows that you can do "interesting" things with it:

ClearAll[x];
b = False;
OwnValues[x] = {x :> (b = False; 1) /; b, x :> (b = True; -1) /; ! b};

This way, the "value" of x after evaluation depends on the state of the boolean b. As the OwnValues of x contain rules with side effects that change the state of b, this implies that the "value" of x changes every time it is evaluated.

Table[x, {10}]

{-1, 1, -1, 1, -1, 1, -1, 1, -1, 1}

$\endgroup$
  • 9
    $\begingroup$ One can define conditional OwnValues, where rules other than the first may apply. For example, x /; TrueQ[y] := 1;x /; ! TrueQ[y] := 2;. By default, the second rule applies. If you set y to True, the first rule will apply. So, your answer is not fully correct as written. $\endgroup$ – Leonid Shifrin Jul 5 '18 at 22:42
  • 1
    $\begingroup$ @Leonid That's worthy of an answer, is it not? :-) $\endgroup$ – Mr.Wizard Jul 5 '18 at 22:47
  • $\begingroup$ @Mr.Wizard I don't think so :) If it gets incorporated into Henrik's answer in some form, I will be happy. $\endgroup$ – Leonid Shifrin Jul 5 '18 at 22:48
  • 1
    $\begingroup$ @HenrikSchumacher Sure. Since the first matching rule is also the strategy for other ...Values, the OwnValues is not that different from them in this respect. The difference is really that it is much harder to find an uncontrived example of multiple OwnValues for the same symbol, because that would mostly mean using a symbol like a function that would depend on global variables. $\endgroup$ – Leonid Shifrin Jul 6 '18 at 17:36
  • 3
    $\begingroup$ @RobertJacobson Of course it is. $\endgroup$ – Henrik Schumacher Jul 8 '18 at 9:35
7
$\begingroup$

The answer is yes, as Henrik Schumacher's answer pointed out. Leonid Shifrin gave a more natural way to get multiple OwnValues in the comments to Henrik's answer. However, the situation is more complicated and appears to expose some undefined/inconsistent behavior.

Unconditional Assignments

As Henrik's answer explains, one can write to OwnValues[x]:

ClearAll[x];
OwnValues[x] = {x -> 1, x :> 2};
OwnValues[x]
{HoldPattern[x] :> 1, HoldPattern[x] :> 2}

Whether or not an OwnValue is a Set or SetDelayed is not reported by OwnValues[x] but is reported by Definition[x]:

Definition[x]
x = 1 

x := 2 

The ordering of OwnValues[x] matters. The first rule (actually, the first rule that matches, see below) determines what x evaluates to.

Setting OwnValues[x] directly should be avoided, as it can lead to inconsistent behavior (see last section) and can circumvent Mathematica's behavior of placing more specific rules before more general rules as described in the documentation:

If a new rule that you give is determined to be more specific than existing rules, it is, however, placed before them. When the rules are used, they are tested in order.

Conditional Assignments

Leonid Shifrin provides another way to obtain multiple OwnValues, namely conditional assignment. The placement of the condition determines whether the rule is prepended or appended:

ClearAll[x];
(* Appends the rules to OwnValues[x]. *)
x /; TrueQ[y] := 1;
x /; !TrueQ[y] := 2;

(* Prepends the rules to OwnValues[x]. *)
x := 4 /; EvenQ[y];
x := 1 /; OddQ[y];
OwnValues[x]
{HoldPattern[x] :> 4 /; EvenQ[y], HoldPattern[x] :> 1 /; OddQ[y], 
 HoldPattern[x /; TrueQ[y]] :> 1, HoldPattern[x /; ! TrueQ[y]] :> 2}

The first rule that matches is what x evaluates to. (Note that this example uses SetDelayed.)

Set versus SetDelayed

With existing OwnValues

The behavior of Set is different from SetDelayed. Multiple OwnValues of the form x /; TrueQ[y] = 1; (condition on the lhs) can coexist with each other and with any form of SetDelayed:

ClearAll[x];
x /; TrueQ[y] = 1;
x /; ! TrueQ[y] = 2;
x := 3;
OwnValues[x]
{HoldPattern[x] :> 3, HoldPattern[x /; TrueQ[y]] :> 1, 
HoldPattern[x /; ! TrueQ[y]] :> 2}

However, a call of the form x = 1 or x = 2 /; EvenQ[y] (condition on the rhs) will always clear any existing members of OwnValues[x], no matter its contents:

ClearAll[x];
x /; TrueQ[y] := 1;
OwnValues[x]

x = 2 /; EvenQ[y];
OwnValues[x]
{HoldPattern[x /; TrueQ[y]] :> 1}

{HoldPattern[x] :> 2 /; EvenQ[y]}

This is not true of (unconditional) SetDelayed which only replaces the first rule of the form x:>1 or x->1 in OwnValues[x], if such a rule exists:

ClearAll[x];
OwnValues[x] = {x -> 1, x -> 2}; (* However, see last section. *)
x /; TrueQ[y] := 3;
OwnValues[x]

x := 4;
OwnValues[x]
{HoldPattern[x] :> 1, HoldPattern[x] :> 2, 
HoldPattern[x /; TrueQ[y]] :> 3}

{HoldPattern[x] :> 4, HoldPattern[x] :> 2, 
HoldPattern[x /; TrueQ[y]] :> 3}

With subsequent conditional assignments

A similar pattern holds for subsequent conditional assignments (although see last section). First with Set:

ClearAll[x];
x = 1;
OwnValues[x]

x /; TrueQ[y] := 2;
OwnValues[x]
{HoldPattern[x] :> 1}

{HoldPattern[x /; TrueQ[y]] :> 2}

Now with SetDelayed:

ClearAll[x];
x := 1;
OwnValues[x]

x /; TrueQ[y] := 2;
OwnValues[x]
{HoldPattern[x] :> 1}

{HoldPattern[x] :> 1, HoldPattern[x /; TrueQ[y]] :> 2}

Inconsistent/Undefined Behavior

It matters how a Set rule is placed into OwnValues[x]: whether by writing directly to OwnValues, OwnValues[x] = {x->1}, or "indirectly", x = 1.

ClearAll[x];
OwnValues[x] = {x -> 1};
x /; TrueQ[y] := 2;
OwnValues[x]
{HoldPattern[x] :> 1, HoldPattern[x /; TrueQ[y]] :> 2}

Compare to

ClearAll[x];
x = 1;
x /; TrueQ[y] := 2;
OwnValues[x]
{HoldPattern[x /; TrueQ[y]] :> 2}

(As previously stated, an unconditional SetDelayed will overwrite the first x->1 rule.)

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.