I would like something like that:
makeActiveBinding("f", function() {
called_as_a_function <- ... # <- insert answer here
if(called_as_a_function) {
sqrt
} else {
1
}
}, .GlobalEnv)
# Expected output
f + f
#> 2
f(4) + f
#> 3
I use f
here, should work with any function
In the example above f
returns 1
and f(4)
returns sqrt(4)
. In my real use case the naked f
(not f()
) will return a function object, so the workaround proposed by Michal cannot be used as is.
I use +
here for simplicity, but it might be any function or none, including NSE functions like quote()
, so for instance quote(f)
and quote(f())
should not have their input changed by the solution.
I tried to play with the sys.calls()
but couldn't get anything robust.
Answers using low level code are welcome too, who knows maybe dark magic can help.
These won't be called at the top level so if you cannot make the above work but can get the following to work for instance that's good too, and in practice it won't be the .GlobalEnv
so if you can make it work in another environment that's good too.
identity(f + f)
#> 2
identity(f(4) + f)
#> 3
If you have solutions that just get me closer you might post them, for instance if your solution works only if f
and f()
are not used in the same call it's still useful to me.
Since I was asked about the real context here it is, but solving the above is all I ask.
- My package {boomer} provides a way to curry a function
f
by modifying its environment and populating its new enclosure with shims of every functionf
calls, we say that werig
f
. - These shims print the calls and their outputs, but behave the same apart from side effects, so
f
and riggedf
are expected to return the same - However if the shims are returned, or if their body is manipulated by
f
, the output will be unexpected - By treating
shim
andshim()
differently I avoid the more obvious corner cases,shim()
will show side effects, andshim
would return the original function.
The issue is here and package in action is showed here
And also tbh I'm generally curious about if it's possible.
f
is a curried function, if it's called, I want the curried function to be called, if it's returned, or asked forbody(f)
for example, I want my original uncurriedf
to be used. I see how it might be used for evil, but I promise to use it for good ;). – Aerielf2(f + f(4))
. Otherwise, it would seem like you would need to be able to parse the original expression before being evaluated. – Psychologism{
to be thisf2
function since these calls would form the body of another function in my use case. – Aeriel