coro
coro copied to clipboard
programmatic async function creation
It would be nice to programmatically create an async function, such as when you want to convert an expression into an anonymous function.
An example interface could be:
as_async_function(
{ await(foo) }
)
At the moment we can only pass anonymous functions to coro::async
because of the substitute call in coro::: assert_lambda
. Technically I could use coro:::generator0(fn, type = "async")
, but it seems it's not exported for a reason.
You can get half of the way with rlang::inject
, but it's a bit hacky and you can't use it to set the formals of the anonymous function.
inject()
is a valid approach to metaprogramming. But I wonder, from what information would you generate the formals? I think you're looking for the equivalent of rlang::new_function()
where you'd pass formals, env, and body individually?
Right, I was looking exactly for something analogous to rlang::new_function
. I was trying to modify the formals via formals
but that seems to not work as expected, and also drops the aync function class
As an aside, I don't mean to suggest inject
is hacky, more that it feels like a workaround. Technically I can create an anonymous function through rlang::new_function
, but that will end up as a name when passed to assert_lambda
The tricky part is that async()
takes calls to function
instead of evaluated functions.
These calls are a bit tricky, see as.list(quote(function(foo) bar))
for the contents. The second element is a pairlist not a list.
If you create a call following this structure (e.g. turn the result of the previous example back to a call with as.call()
), then you can inject it inside async()
.
I agree a new_
function would be much better.