How can I create an operator that holds its arguments?
I am looking to define something similar to
oper[x_][expr_] := Hold[expr]
I am expecting the following behaviour:
oper[1][1+1]
(* Hold[1+1] *)
Of course, the above does not keep expr evaluated, and we cannot set HoldAll on oper[x_] (only on oper itself).
A common solution is
ClearAll[oper]
oper[x_] := Function[{expr}, Hold[expr], {HoldAll}]
but now oper[1] will evaluate. I want to keep it unevaluated.
oper[1]
(* Function[{expr}, Hold[expr], {HoldAll}] *)
I assume this is possible because ResourceFunction manages to pull it off.
ResourceFunctiondoes this? I've looked at the code quite a bit in the past, and haven't noticed anything like this. – Lukas Lang Apr 09 '20 at 15:44GeneralUtilities`PrintDefinitions@ResourceFunctionlooks up the stack to see if it is being applied to subvalues and, if not, returns unevaluated. – WReach Apr 09 '20 at 15:50ResourceFunctioncan both hold subvalue arguments and appear to remain unevaluated when not applied to any arguments. Emphasis on "appear" since even though it does actually evaluate, the display form looks makes it look like it didn't. The implementation could have gone all the way and used the technique that Leonid linked (but didn't). – WReach Apr 09 '20 at 16:10