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

serializable anonymous functions #38

Merged
merged 2 commits into from
Sep 19, 2023

Conversation

achille-roussel
Copy link
Contributor

This PR adds the ability to have anonymous functions on the call path of coroutines, including being able to serialize them.

I didn't really do it on purpose but it seems that when the function literal is injected directly as argument to a function call, it does not get captured in the coroutine state and remains inlined in the code (which is optimal I believe?).

I removed checks in unsupported which were getting in the way of supporting function literals, tho I don't fully understand the reasons why those checks were here in the first place so I could use a review on that @chriso

Signed-off-by: Achille Roussel <[email protected]>
Comment on lines 19 to 21
if countFunctionCalls(nn, info) > 1 {
err = fmt.Errorf("not implemented: multiple function calls in an expression")
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to desugar statements that have multiple function calls, e.g.

foo[bar()] = a() + b() + c(d() + e(f()))

If more than one of these functions contains a yield point, when resuming how do we ensure that we call the right function and skip the functions that we already have a result for?

My plan was to desugar statements by hoisting function calls out into temporary variables, e.g.

_a := a()
_b := b()
_d := d()
_f := f()
_e := e(_f)
_c := c(_d + _e)
_bar := bar()
foo[_bar] = _a + _b + _c

These will then be assigned their own IP, and we'll be able to skip to the right point when resuming after a yield.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not all function calls will contain a yield point, so the desugaring above is the worst case. Could we detect (given an ast.CallExpr) whether the called function is or contains a yield point, and only reject expressions with more than one of these per statement?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, now I remember you mentioning it before.

I'll look into desugaring expressions containing function calls first 👍 if it turns out to be too much of a hassle, then we can apply a restriction instead.

Signed-off-by: Achille Roussel <[email protected]>
@achille-roussel
Copy link
Contributor Author

I added the multi-call check back and commented out the test that depends on desugaring function calls so we can merge this PR.

@achille-roussel achille-roussel merged commit 52df481 into main Sep 19, 2023
2 checks passed
@achille-roussel achille-roussel deleted the serializable-anonymous-functions branch September 19, 2023 17:34
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

Successfully merging this pull request may close these issues.

3 participants