Consider these definitions:
own = "OwnValue";
down[_] = "DownValue";
sub[_][_] = "SubValue";
N[n] = 3.14;
_[___, up, ___] ^= "UpValue";
The attribute HoldAllComplete
holds an UpValue but it also holds the other Values as well.
Without advance knowledge of the symbol up
how can I evaluate everything but the UpValue?
Set
and related functions appear to have this evaluation property internally:
f[own, down[1], sub[1][2], N[n], up] = 1;
Definition[f]
f["OwnValue", "DownValue", "SubValue", 3.14, up] = 1
The first idea that comes to mind is to test if a symbol has an UpValue and skip evaluation if it does, but this proves problematic. First, a symbol can have both an OwnValue and an UpValue, and the OwnValue should be used if possible:
x[up3] ^= 2;
up3 = 1;
f[up3]
f[1] (* desired output *)
Second, testing for an UpValue can be difficult:
_[___, up4, ___] ^= {};
UpValues[up4] === UpValues[Plus]
True
To clarify, it is not my intent to return f[. . ., up]
as output, which would require Defer
or similar. Rather I would like to handle the expression f[. . ., up]
as an argument like Set
does, or define a function f[args___] := . . .
(with attribute HoldAllComplete
) that returns e.g. {"OwnValue", "DownValue", "SubValue", 3.14, HoldComplete[up]}
How can this be achieved?
f[up]=1
,up
appears at the second level. This is the reason why theUpValue
does not evaluate. Considerx=up
(which isSet[x,up]
)---this evaluates to"UpValue"
right away. Now trySetAttributes[fun, HoldAll]
andfun[p[up]]
---this one does not evaluate because UpValues are evaluated only in the first level of held heads (just likeUnevaluated
,Sequence
, etc.) $\endgroup$