SubValues
, as discussed in a previous question, are declared as follows
f[x_][y_] := {ToString[Unevaluated[x]], ToString[Unevaluated[y]]}
But, attempting to use SetAttributes
on f
only affects the DownValues
of f
during evaluation, not the SubValues
. In other words, if HoldAll
is set on f
, then only x
, in the above code, is held. In code,
SetAttributes[f, HoldAll]
f[ 1 + 2 ][ 3 + 4 ]
(*
==> { "1 + 2", "7" }
*)
Attempting to use SetAttributes
on f[x]
results in the error
SetAttributes::sym: "Argument f[x] at position 1 is expected to be a symbol."
and, similarly, for f[x_]
simply because neither are symbols.
A work around is not to set a SubValue
directly, but, instead, return a pure function and use the third argument to set the attribute, as follows
SetAttributes[g, HoldAll]
g[x_] := Function[{y},
{ToString[Unevaluated[x]], ToString[Unevaluated[y]]},
{HoldAll}
]
g[ 1 + 2 ][ 3 + 4 ]
(*
==> {"1 + 2", "3 + 4"}
*)
But, SubValues[g]
returns an empty list, indicating that while equivalent, this construct is not processed in the same manner.
So, how does one set the attributes on f
such that the SubValues
are affected during evaluation?
f
on each following sub value but againf
will be aDownValue
. Not sure if this helpes or valid to be an answer but I thought to share it.ClearAll[f2]; SetAttributes[f2, HoldAll]; f2[x_] := (AppendTo[l, ToString@Unevaluated[x]]; f2);
and thenl = {}; f2[3 + 4][2 + 5][3 + 34]; l
which gives{"3 + 4", "2 + 5", "3 + 34"}
$\endgroup$