My program creates an object based on an Association, with a custom head:

g = Gate[<| "key1" -> val1 |>]

I have given it an UpValue for Lookup to behave nicely with it:

Lookup[Gate[assoc_], a___] ^:= Lookup[assoc, a]

I would like to be able to use the Lookup list syntax to return {val1, val2} in both the following lines:

Lookup[{ <| "key1" -> val1 |>, <| "key1" -> val2 |> }, "key1"]
Lookup[{Gate[ <| "key1" -> val1 |> ], Gate[ <| "key1" -> val2 |> ]}, "key1"]

The obvious thing to try is the following:

Gate /: Lookup[{a___, Gate[b_], c___}, d___] := Join[Lookup[{a}, d], {Lookup[b, d]}, Lookup[{c}, d]]

I get the TagSetDelayed::tagpos error, of course, because I'm trying to assign Gate a value from the second level of the expression Lookup[List[Gate[]]]. (Ignore for now the fact that Lookup[{}, key] returns a Missing expression rather than {}, and so even if TagSetDelayed were clever enough, the assignment above would still fail to do what I wanted. I can deal with that afterwards.)

The "other question in mind" question from this StackExchange question is basically my question, but I don't think it's answered there.

Is there a workaround that doesn't require me to replace Lookup with a special GateLookup function I define myself?

More generally, are there any workarounds to TagSetDelayed::tagpos which don't involve creating helper functions and going full object-oriented?


1 Answer 1


I am not aware of any good workaround (if you insist on using the same syntax) - the depth-1 limitation for UpValue search is pretty restrictive.

You may try something like this:

Gate /: {a___, Gate[b_], c___} := 
  {a, b, c} /; MatchQ[Stack[_][[-5]], HoldForm[Lookup[_List, _]]]

but I can't say how robust this is, and also this would induce additional overhead.

That said, most such issues are syntactic in nature, and often the better way out would've been to give up the standard syntax (Lookup etc), but instead define your own data type with all required methods, where you can impose the names and syntax you like.


Your Answer

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

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