28
$\begingroup$

Some of the big mysteries of Universe Mathematica for me is the application of UpValues. I know about this question and know the very poor Mathematica documentation on that. I'm very curious to know if someone that not @Leonid uses this too.

Just to get some clue on how it works, I would like to know what's the difference between TagSet and UpSet. Can I say that UpSet is subset of TagSet?

For instance, I can say these examples are equivalent.

name[alien]^= "Alf"    
alien /: name[alien] = "Alf"

In what situations should I apply each case?

$\endgroup$
10
  • 1
    $\begingroup$ In addition to the answer of @Mr.Wizard, I discussed exactly this issue in this answer (last subsection), where it is put in a wider context of UpValues in general. $\endgroup$ Commented Jan 25, 2013 at 10:11
  • $\begingroup$ Tks @LeonidShifrin, It was very helpfull. $\endgroup$
    – Murta
    Commented Jan 26, 2013 at 0:52
  • $\begingroup$ Murta, I see that you did not Accept my answer. Is there something I can do to make it more satisfactory? $\endgroup$
    – Mr.Wizard
    Commented Feb 27, 2013 at 8:31
  • 2
    $\begingroup$ @Mr.Wizard Re: UpSet vs TagSet - the only practical difference I am aware of is that TagSet is more precise, and will only add an UpValue to a symbol you specify, while UpSet will add UpValues for all symbols at the first level in the l.h.s. of the rule. Re: email change - the funny this is, I didn't change it! Apparently, SE changed the algorithm they use to compute at least some gravatars. I've noticed it and some other users seem to have been affected by it as well (although not all, it seems). $\endgroup$ Commented Sep 1, 2016 at 12:50
  • 1
    $\begingroup$ @Mr.Wizard There certainly is a difference.When you execute e.g. ClearAll[a, b, c, d]; f[a, b, c] ^= d;, all of the a,b,c get UpValues, whereas when you execute ClearAll[a, b, c, d]; a /: f[a, b, c] = d;, only a does. With more complicated patterns involving blanks, it may matter. Generally, you want to be as precise as possible, to not produce extra global rules besides those you need, because they may fire in unforeseen situations. Actually, we pay for locality of overloading based on UpValues with making it harder to see why a given rule fired. No reason to make it harder still. $\endgroup$ Commented Sep 1, 2016 at 22:52

1 Answer 1

25
$\begingroup$

UpSet and UpSetDelayed make multiple assignments:

UpSet associates an assignment with all the distinct symbols that occur either directly as arguments of lhs, or as the heads of arguments of lhs.

f[a[__], b[__], c[__]] ^:= "UpValue"

UpValues[a]
UpValues[b]
UpValues[c]
{HoldPattern[f[a[__], b[__], c[__]]] :> "UpValue"}

{HoldPattern[f[a[__], b[__], c[__]]] :> "UpValue"}

{HoldPattern[f[a[__], b[__], c[__]]] :> "UpValue"}

TagSet and TagSetDelayed make specific assignments:

k /: g[i[__], j[__], k[__]] := "UpValue"

UpValues[i]
UpValues[j]
UpValues[k]
{}

{}

{HoldPattern[g[i[__], j[__], k[__]]] :> "UpValue"}
$\endgroup$
8
  • $\begingroup$ Is there any meaning to which symbol a rule is assigned to? Maybe who I have to Clear to get rid of it? $\endgroup$
    – masterxilo
    Commented Jul 6, 2016 at 21:09
  • $\begingroup$ @masterxilo I may not understand the question. In the first example above the rule is bound to all three Symbols a, b, and c, whereas in the second example it is only bound to k. $\endgroup$
    – Mr.Wizard
    Commented Jul 6, 2016 at 22:08
  • 1
    $\begingroup$ Yes, I understand that. But does using TagSet have any observable consequence other than that I have to do Clear[a,b,c] in the first example and just Clear[k] to get rid of this rule? $\endgroup$
    – masterxilo
    Commented Jul 7, 2016 at 0:38
  • $\begingroup$ @masterxilo Ah, okay, sorry I didn't understand that the first time. I believe I have experienced at least one case where there are, but at the moment I can't think of an example. Let me get back to you on that. $\endgroup$
    – Mr.Wizard
    Commented Jul 7, 2016 at 0:44
  • 3
    $\begingroup$ @glS I think perhaps the case I was remembering was more simple that I had recalled, and I kept dismissing the simple example as trivial. However I think it is likely that the example at the time did not seem trivial to me which is why I have the memory of it being more profound. Anyway a simple example of a difference is: f[a_Integer, b_foo] ^:= bar which throws a UpSetDelayed::write: Tag Integer in f[a_Integer,b_foo] is Protected message, whereas foo /: f[a_Integer, b_foo] := bar does not. Both still create an UpValue on foo successfully however. $\endgroup$
    – Mr.Wizard
    Commented Sep 1, 2016 at 11:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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