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?
Answer
Does this work as you want to?
SetAttributes[f, HoldAllComplete];
{first, rest___} ^:= HoldComplete[rest]
f[args___] := {first, args}
f[own, down[1], sub[1][2], N[n], up]
HoldComplete["OwnValue", "DownValue", "SubValue", 3.14, up]
Comments
Post a Comment