Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

programmatic async function creation #43

Open
ElianHugh opened this issue Jan 18, 2024 · 3 comments
Open

programmatic async function creation #43

ElianHugh opened this issue Jan 18, 2024 · 3 comments

Comments

@ElianHugh
Copy link

ElianHugh commented Jan 18, 2024

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.

@lionel-
Copy link
Member

lionel- commented Jan 18, 2024

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?

@ElianHugh
Copy link
Author

ElianHugh commented Jan 18, 2024

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

@lionel-
Copy link
Member

lionel- commented Jan 18, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants