1

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.

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
  • @Leonid Thanks! I was looking for that, couldn't find it. – Szabolcs Apr 09 '20 at 13:11
  • But I would keep this question nonetheless, not delete - just close as a dupe. It is very concisely formulated and is something that many users may want at one point in time or other. – Leonid Shifrin Apr 09 '20 at 13:12
  • Can you be a bit more specific on where you think ResourceFunction does 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:44
  • 1
    @LukasLang In V12.1 at least, the first definition in GeneralUtilities`PrintDefinitions@ResourceFunction looks up the stack to see if it is being applied to subvalues and, if not, returns unevaluated. – WReach Apr 09 '20 at 15:50
  • 1
    @WReach But as soon as subvalues are involved, it is replaced by the symbol used for the resource function, so it doesn't really achieve what this question asks for. Essentially, they get away with it because each RF has a symbol assigned to it, and no other kind of metadata needs to be stored in the head (so converting to a symbol is not problematic) – Lukas Lang Apr 09 '20 at 15:55
  • 2
    @LukasLang Fair enough. I think the question is just referring to the fact that a ResourceFunction can 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
  • @WReach Thanks! I used the wrong spelunking tool to look at it and somehow that part went missing. It's clear now. – Szabolcs Apr 09 '20 at 17:04

0 Answers0