Skip to main content

programming - How can I hold UpValues but evaluate other expressions?


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