-
Notifications
You must be signed in to change notification settings - Fork 429
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
Support _ syntax sugar in application. #1804
Support _ syntax sugar in application. #1804
Conversation
Proof of concept to support ? syntax sugar in function application. The implementation is crude just to illustrate the idea, and check that there are no parsing conflicts. An application f(?, 3); is transformed to (__x) => f(__x, 3) This enables the use of pipe in arbitrary positions, as in let l = [1,2,3] |> List.map (i => i+1, ?) |> List.filter (i => i>0, ?); or in let l = (i => i+1) |> List.map(?, [1,2,3]);
The intermediate allocation seems to be killed as well: https://reasonml.github.io/en/try.html?reason=DYUwLgBAhhC8EG0A+BGANBATBgzEguhAFAQRIB8EAdnJQFIDOAdAIIBObUAnkwLZQAHABRCoASlrQIAagjpqEkmUo1Y9Zu048AZgEtgYEGxHjJMSvKpigA Which makes this feature. Otherwise, we wouldn't ship it in its current form. Interestingly, you might be able to use this independently like so: |
@chenglou which intermediate allocation are you referring to? |
|
@chenglou Can't you write
to avoid these allocations today? Or are you thinking about the (This addition is so cool, btw!) |
Yeah. And this generalizes to |
Really like this idea, was thinking could this possibly work with labeled arguments too? |
@SllyQ in principle yes, though it looks like for some reason In fact, just found out by playing that also |
`Some(?)` is tranformed to `__x => Some(__x)`. This explores the idea of unlocking the treatment of constructors as functions. Briefly tried to add ? to arbitrary constructors, not just unary ones, but at leas the obvious attempts give parse conflicts.
What other characters could we use? |
I don't think |
Honestly parsing |
It seems that the existing parsing of `foo(~x=?)` is not intentional, so it’s been removed. Syntactically, the existing `foo(~x?)` and `foo(~x=?None)`, are quite similar to `foo(~x=?)` though the latter has a completely different meaning, nothing to do with optional labels. Alternatively, the underscore “_” symbol is still free in the context where “?” is used here.
It seems that the existing parsing of Syntactically, the existing Alternatively, the underscore |
fwiw I'd probably prefer |
@TheSpyder @jaredly then let's do |
Found by trial and error several places where functions are printed, to convert back from (__x) => foo(__x) to foo(_). Not sure if this is complete.
Actually, we might clear out #1405 with this one too. So which one would you prefer now? let f = switch (_) {
| A => 1
| _ => 2
} let f = switch (?) {
| A => 1
| _ => 2
} |
This form `let unSomeFun = fun | Some(n) => n | None => 0;` can then be expressed as `let unSome = switch _ { | Some(n) => n | None => 0 };`
Add support for pretty printing nested functions such as `x => foo(_);`.
…tion_mark_in_application # Conflicts: # src/reason-parser/reason_parser.mly
I suggest we get some wider feedback on this, to make sure overloading Using it to solve 1405 seemed weird at first, but looking at the code I can see how it's a natural extension of the original use case. However that does make me wonder how many people will see that they're similar or just be confused. |
Just to mention in this thread — there's Proposal to add partial application to JS which uses Personally I like To remove such overloading we could:
|
For the |
Isn’t spread syntax to put the dots at the start? Is that an option? |
@andreypopp a little pedantic, but Since the ES proposal uses |
The proposal for |
Add support for optional labaled arguments, as in `foo(~a=?_)`.
To summarize, at this stage there is support for
The syntactic sugar corresponds to this:
|
Note: it’s not clear what JS is going to do w.r.t. partial application (or if it will ever be supported), therefore I wouldn’t look to JS in this case. |
Scope is an issue. Given:
What is this translated to?
One possibility is to only allow this kind of partial application for operands of the pipe operator. Then the scope is clear. |
@rauschma currently the scope is the direct function application where
is
It would be possible to consider nested scopes, and tie it to the pipe operator. Then one would need to specify what is allowed and what is not. E.g. can it go inside an if-then-else, etc. A small observation: having a mechanism that is not tied to the pipe operator lets you split things apart:
|
Our lambda syntax is already so light-weight, I think sticking with the simple way (just the function being applied) makes sense. b/c if you want more complex things, you can always do |
We did consider tying this to the pipe operator, but it was actually easier to implement the way we did it now (i.e. as a standalone partial app feature). Consider it a nice addition that it works outside of pipes. I do believe it can be confusing though; maybe can discourage them socially for now I think |
Proof of concept to support
?
as syntax sugar in function application.The implementation is crude, just to illustrate the idea, and check that there are no parsing conflicts. (No printer implementation at the moment).
An application
f(?, 3);
is transformed to
(__x) => f(__x, 3);
This enables the use of pipe in arbitrary positions, as in
let l = [1,2,3] |> List.map (i => i+1, ?) |> List.filter (i => i>0, ?);
or in
let l = (i => i+1) |> List.map(?, [1,2,3]);