Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

With Mathematica 10, I wanted to overload Lookup using TagSetDelayed, but it doesn't work. For instance, if I define two objects with head TempHead

t1 = TempHead[a -> 1, b -> 2, c -> 3];
t2 = TempHead[c -> 3, d -> 4, e -> 5];

I can overload Plus as usual:

TempHead /: Plus[t1_TempHead, t2_TempHead] := TempHead @@ Join[List @@ t1, List @@ t2]


t1 + t2
(* TempHead[a -> 1, b -> 2, c -> 3, c -> 3, d -> 4, e -> 5] *)

But, if I do the same thing with Lookup, it doesn't work:

TempHead /: Lookup[t1_TempHead, t2_TempHead] := TempHead @@ Join[List @@ t1, List @@ t2]
(* Lookup::invrp: The argument TempHead[a->1,b->2,c->3] is not a valid Association or a list. >> *)

Further, you cannot even use Unprotect to overload Lookup. I thought this was a bug, but when I reported it to Wolfram, they said Lookup was designed to give an error on all objects that aren't Associations. Certainly there are Mathematica functions that give errors (e.g. Part, when you try to access outside the length of a List), but you can usually still overload them. Does anyone know if there is a good reason for implementing Lookup this way? It seems to break with the "Everything is an expression" principle that Wolfram is always touting. Are there other symbols that act like Lookup?

share|improve this question
You seem to misunderstand what ´TempHead /: Lookup[t1_TempHead, t2_TempHead]´ actually does (which caused some confusion for RunnyKine and m_goldberg, see below): It adds a definition to (the UpValues) of ´TempHead´, not to ´Lookup´. That's why unprotecting ´Lookup´ doesn't help of course. – sebhofer Aug 20 '14 at 23:40
up vote 8 down vote accepted

Warning: Modifying a built-in function is not advised

As @m_goldberg already stated, Lookup has Attributes HoldAllComplete, so a workaround will be to remove this Attribute:

Edit: As per m_goldberg's recommendation

attr = Attributes[Lookup];
Attributes[Lookup] = {};


t1 = TempHead[a -> 1, b -> 2, c -> 3];
t2 = TempHead[c -> 3, d -> 4, e -> 5];

TempHead /: Lookup[t1_TempHead, t2_TempHead] := TempHead @@ Join[List @@ t1, List @@ t2]


Lookup[t1, t2]

Gives the desired output:

TempHead[a -> 1, b -> 2, c -> 3, c -> 3, d -> 4, e -> 5]

Remember to restore the Attributes when you're done

Attributes[Lookup] = attr;
share|improve this answer
Don't you think removing HoldAllComplete is dangerous to the normal functioning of LookUp? – m_goldberg Aug 20 '14 at 20:25
@m_goldberg Well, Unprotecting any built-in function and modifying it is "dangerous" to the normal functionality of that function :) – RunnyKine Aug 20 '14 at 20:27
@m_goldberg, I have added that disclosure but I need you to clarify something for me. Is this question by itself not assuming a modification of a built-in function? If so, shouldn't the OP add that disclosure? – RunnyKine Aug 20 '14 at 20:35
I don't think the OP contemplated modifying any built-in functions. He seems unaware of the difference between standard evaluation and non-standard evaluation, so he thought creating up-values, which does not involve modifying built-ins, would work. Modifying Lookup may be required, but it was not assumed a priori. – m_goldberg Aug 20 '14 at 20:43
The OP clearly states: "I wanted to overload Lookup using TagSetDelayed. – eldo Aug 20 '14 at 20:55

Lookup has the attribute HoldAllComplete, which means the kernel evaluator will not see its arguments and, therefore, will not look at its up-values.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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