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?
fon each following sub value but againfwill 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]; lwhich gives{"3 + 4", "2 + 5", "3 + 34"}$\endgroup$