# How can you Unset the following UpValues?

This expression is taken from a talk given by the late Robby Villegas. The UpValues to some symbol a is defined below as:

ClearAll["a"];
a /: _[___, a, ___] := (Print["a fired"]; Null)


Nothing I tried could Clear the definitions associated with the symbol. Is there a way to clear the associated UpValues.

• Regardless of the method to solve this problem, I will mention that giving such generic UpValues to symbols is outright dangerous. Speaking from experience here, I have tried to use this kind of rules before, and it was invariably biting me later - so I never ended up leaving such constructs in final code in whatever I was doing. Sep 8 '18 at 17:33

Note that you could clear all of the *Values by using Clear["a"] or ClearAll["a"]. However, if you only want to clear this particular UpValues you could make use of the fact that HoldAllComplete prevents UpValues from firing. So, temporarily give TagUnset this attribute. Here's your UpValues definition:

ClearAll["a"];
a /: _[___,a,___] := (Print["a fired"];Null)


Give TagUnset the HoldAllComplete attribute, and unset the above definition:

InternalInheritedBlock[{TagUnset},
SetAttributes[TagUnset, HoldAllComplete];
TagUnset[a, _[___,a,___]]
]


Check:

UpValues[a]


{}

• Thanks. Very neat. Sep 9 '18 at 20:04
a /: Except[TagUnset, _][___, a, ___] := (Print["a fired"]; Null);

f[a]
(* a fired *)

(* As we can see below, usage of ClearAll does not work *)

ClearAll[a]
(* a fired *)

(* now removing the associated values using the TagUnset Head *)

TagUnset[Unevaluated[a],HoldPattern[Except[TagUnset, _][___, a, ___]]];

f[a]
(* f[a] *)
`
• I think both the Unevaluated and the HoldPattern are unnecessary. Sep 9 '18 at 6:48
• @Carl .. though unnecessary but I think it is a safe practice Sep 9 '18 at 20:05