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
rfc: phase-independent functions with ?inflight keyword #1711
Conversation
Another idea/suggestion is to designate these functions with the keyword |
Im on board, I just dont much care for the prefixed |
I agree that letting the compiler infer whether a function is phase-independent is not the right way to go. Like @hasanaburayyan, I'm also not crazy about the I'm also OK with experimenting with having to always put a phase modifier on functions, and then we have |
@Chriscbr , great doc |
Perhaps an alternative is to create functions that are neither This type of function only becomes something like // a template function, if no variable receives this template function
// with a prefix (pre/in) the compiler gives an error
let f = flight(...) { ... };
let p = pre f; // create a preflight function
let i = in f; // create a inflight function |
Maybe I'm missing something, but I think any project has general purpose utility functions that are used throughout the code and have no business being confined to only one phase. For example: sorting an array with different algorithms |
Yes, I think @ShaiBer 's answer is correct, the main use case that comes to my mind is utility functions that do not need to be restricted to one phase or another. If I think of any more use cases I'll update the proposal. BTW, my initial guess is we don't need this feature for beta, or at least we should dogfood more before considering it. @marciocadev that's a very interesting idea! From an implementation angle, I think that could be a good option if we want to simplify modeling phase-independent functions in the compiler (perhaps we would only need our But I'm a little cautious about templating based solutions / not sure I understand the benefits. In your example, suppose I use a preflight function inside |
I was thinking in gives an error if Some errors bring cloud;
let f = flight ( ... ) { ... } // ERROR, something like f variable never used bring cloud;
let f = flight ( ... ) { ... }
new cloud.Function(pre f); // ERROR, can not pass a preflight to cloud.Function This works bring cloud;
let f = flight ( ... ) { ... }
new cloud.Function(in f); // WORKS Somehow, I think of a bring cloud;
let f = flight ( ... ) { ... } // verify some data
let p = pre f;
if (p.invoke() == false) { // verify before create the cloud.Function (preflight)
...
}
let i = in f;
new cloud.Function(inflight(event: str): str => {
...
if (i.invoke() == true) { // verify inside cloud.Function (inflight)
...
}
...
}
if (p.invoke() == true) { // verify after create the cloud.Function (preflight)
...
} or the same without create new variables bring cloud;
let f = flight ( ... ) { ... } // verify some data
if ((pre f).invoke() == false) { // verify before create the cloud.Function (preflight)
...
}
new cloud.Function(inflight(event: str): str => {
...
if ((in f).invoke() == true) { // verify inside cloud.Function (inflight)
...
}
...
}
if ((pre f).invoke() == true) { // verify after create the cloud.Function (preflight)
...
} |
Another naming suggestion from @MarkMcCulloh is "unphased" |
Hi, This PR has not seen activity in 20 days. Therefore, we are marking the PR as stale for now. It will be closed after 7 days. |
Hi, This PR has not seen activity in 20 days. Therefore, we are marking the PR as stale for now. It will be closed after 7 days. |
Hi, This PR has not seen activity in 20 days. Therefore, we are marking the PR as stale for now. It will be closed after 7 days. |
I'd expect Wing to infer the phase of the function most of the time, and also cast a function to inflight if necessary. In the same way that TypeScript can infer that the following function returns a number: export const sum = (a: number, b: number) => {
return a + b;
}; Regarding Chris' point:
I like Mark's Here's how I'd like it to work in different scenarios: Compiler infers that the function is inflight
Compiler can cast phase-independent functions to inflight (if they don't interact with resources nor capture mutable state)
Compiler infers the function is inflight so it has access to bucket's inflight API
Compiler infers that "put" is preflight because it accesses the bucket
Compiler infers that "append" is preflight because it captures mutable state
|
Hi, This PR has not seen activity in 20 days. Therefore, we are marking the PR as stale for now. It will be closed after 7 days. |
Inspired by a recent post on the Rust blog about how "maybe-async" and "maybe-const" type signatures could be supported in the Rust ecosystem, I thought it could be interesting to consider a syntax for defining phase-independent functions in Wing using the
?inflight
keyword. This doc proposes how it would look and how it would work. Related to #474 and #435From a compiler perspective, these functions would essentially be code generated in both the preflight JS class and the inflight JS class.
Alternatives considered
Let the compiler infer whether a function can be phase-independent
In this model, all functions are phase-independent by default, and capturing a resource would automatically make it a preflight function.
In my opinion, the phase of a function isn't something the compiler should infer -- not because it's not technically feasible, but of user experience problems it could introduce.
In the future, devs will be able to create a Wing libraries that export resources with public preflight methods and public inflight methods. When using a Wing library, consumers should be able to rely on the fact that the method always works in that phase in the future, even if it the implementation changes -- just like today you can rely on the fact that a if a imported TypeScript function returns a boolean, then it will always return a boolean in the future (unless there is a breaking change).
If the compiler inferred whether a function should be phase-independent or preflight, then changing the implementation of the function so that it captures some mutable data could change the function's type to preflight, thus causing a potentially breaking change to consumers.
Make phase-independent functions the default, and add
preflight
as a function modifier insteadI think the idea of functions being phase-independent as the default could be interesting. But I feel like it might be more confusing since a lot of the Wing language is currently designed around the concept that "the top level of your code is preflight" -- for example, creating a bucket at the top-level scope of a Wing file happens in preflight. And the default constructor of a resource is its preflight constructor, which matches up with that.
Put another way, I think preflight-only functions will be more common than phase-independent functions, so I think there should be more friction for the phase-independent use case than the preflight code use case. But this is definitely something we can experiment with.
By submitting this pull request, I confirm that my contribution is made under the terms of the Monada Contribution License.