-
Notifications
You must be signed in to change notification settings - Fork 90
First-class functions/closures as resources #278
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
Comments
Partially answering my own question:
|
The main challenge with first-class functions is the lifetime of the closure state. If a consumer component can import an interface exported by a producer component that contains a first-class function as a parameter, then the consumer's closure state ends up being "owned" by the producer component, which very quickly leads to producer/consumer ownership cycles of the type that I was just, coincidentally, describing yesterday here. That being said, based on the discussions near the end of this issue, there is a new idea for a new restricted form of callback, which is a callback that is scoped to a call (with the same rules as how a Based on this, we could say that the problem with general (unscoped) first-class functions is that they have indeterminate lifetime (b/c agreed that reentrancy is not necessarily a problem if opted into). Also, if you squint, the indeterminacy of callback lifetimes is at the heart of the problems described here that motivate "structured concurrency". |
The the child-handles branch looks very interesting! I haven't thought it that much through, but it seems like a potential solution indeed. At the same time, I'm having a hard time envisioning how pleasant the experience will be for developers authoring components in basically any language that isn't Rust. For many developers, As an alternative for the cycle problem, maybe we could introduce a general purpose
The annotation-less variant is definitely not as rigorous as your proposal, though. |
From a dynamic language perspective (or a statically-typed language that doesn't have a good way to express lifetimes in types), I think we can get away with just a single value that represents all handles, reflect these different scopes as different dynamic rules for when a handle value is "live" and when it is "dead" and will throw (or otherwise fail) when accessed. This is already a common pattern in dynamic language APIs whenever "lifecycles" or dynamic ownership transfer is involved (e.g., see |
I was wandering, now that resources/ownership/borrowing/etc are properly part of the component model; In what way are closures not "just" single-method resources? Can they piggy back off of the semantics and restrictions defined for resources?
For example, given the imaginary interface (& syntax):
Assuming that the following resource types are (automatically?) defined somewhere
how is the first example different than this:
?
By (re/ab)using resource semantics, this would keep function "references" in the realm of acyclic dependencies a.k.a. "no global GC required", right?
The text was updated successfully, but these errors were encountered: