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

[FS-1047] - match! (match-bang) #4427

Merged
merged 26 commits into from
May 25, 2018
Merged

[FS-1047] - match! (match-bang) #4427

merged 26 commits into from
May 25, 2018

Conversation

jwosty
Copy link
Contributor

@jwosty jwosty commented Mar 4, 2018

RFC FS-1047

I've implemented a version of match! that works on my fork. However, since I've been working on Mono & OSX, and I do not have access to a Windows machine for the next few days, I haven't been able to write any kind of tests for this (though I'm not sure where they would go, anyway). Any help or pointers on this matter would be much appreciated (e.g. where are the computational expression tests)

@msftclas
Copy link

msftclas commented Mar 4, 2018

CLA assistant check
All CLA requirements met.

@jwosty
Copy link
Contributor Author

jwosty commented Mar 4, 2018

Here's a quick little sample program using the new syntax for anyone to reference: https://gist.github.com/jwosty/bc7e1723477ea4c300e1fe6a2581d687

@cartermp
Copy link
Contributor

cartermp commented Mar 4, 2018

@jwosty Thanks so much for the contribution! I'm sure @dsyme will offer a thorough review here, and likely have additional ideas about tests.

For now, you can add some tests here: https://github.com/Microsoft/visualfsharp/tree/master/tests/fsharp/core/patterns

Async.Sleep 1
return Hearts }

Async.RunSynchronously <| async {
Copy link
Contributor

@forki forki Mar 5, 2018

Choose a reason for hiding this comment

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

can you please reverse it so that it does not use <|

@jwosty
Copy link
Contributor Author

jwosty commented Mar 5, 2018

Alright, trying out adding some tests.

@forki
Copy link
Contributor

forki commented Mar 5, 2018

cool stuff. would love to use it

/cc @tpetricek

@jwosty
Copy link
Contributor Author

jwosty commented Mar 5, 2018

Me too :) I have a lot of use cases for this in my own projects

@forki
Copy link
Contributor

forki commented Mar 5, 2018

same here. lots and lots of let! followed by match - but inside task { }. since you did not touch FSharp.Core (so no change to async builder) I assume it would automatically work for tasks and promise builder as well?

@realvictorprm
Copy link
Contributor

@jwosty ping me for a review, I'll also test it.

@jwosty
Copy link
Contributor Author

jwosty commented Mar 5, 2018

Yep, it works with any computation expression. It's purely a compiler trick that desugars it into a let! and a normal match

EDIT: technically, it's actually a function

@realvictorprm
Copy link
Contributor

@jwosty that's usually the trick with compilers 😄
Reminds me of the string interpolation. It's just a desugaring to string.concat with calls to "ToString" 😉

@forki
Copy link
Contributor

forki commented Mar 5, 2018

@jwosty that's pretty nice!

@jwosty
Copy link
Contributor Author

jwosty commented Mar 5, 2018

@realvictorprm I'd love that; I don't actually have easy access to a Windows machine (so its a little trickier to pull off the testing)

@forki sweet and simple does the trick! In fact I originally suggested having it optionally emit a new computation builder method (BindPattern or something), but @dsyme wanted to go the simpler route. Makes sense in the end; doesn't require any core library changes

@jwosty
Copy link
Contributor Author

jwosty commented Mar 5, 2018

Also something to keep track of: What tooling changes should take place that would correspond to this? Which repos?

@forki
Copy link
Contributor

forki commented Mar 5, 2018

@jwosty what kind of tooling changes to you mean?

@jwosty
Copy link
Contributor Author

jwosty commented Mar 5, 2018

@forki As in, IDE stuff. E.g. syntax highlighting doesn't recognize it (at least in the way it appears in VS for Mac). Actually, syntax highlighting might be it -- I can't think of how it would effect intellisense

@forki
Copy link
Contributor

forki commented Mar 5, 2018

@jwosty I think VS for Mac can't show it as keyword until @nosami updates the FCS that will bring your changes. So that will take a while.

@vasily-kirichenko do you know where FCS taks keywords from?

@jwosty
Copy link
Contributor Author

jwosty commented Mar 5, 2018

@forki I see

@auduchinok
Copy link
Member

auduchinok commented Mar 5, 2018

@forki It's available in public API via Microsoft.FSharp.Compiler.SourceCodeServices.Keywords.
Internally it is defined in Microsoft.FSharp.Compiler.Lexhelp module.
https://github.com/Microsoft/visualfsharp/blob/f214dcc38f6d34db8902eb40bd5b037ade59a67c/src/fsharp/service/ServiceLexing.fsi#L237-L238
https://github.com/Microsoft/visualfsharp/blob/f214dcc38f6d34db8902eb40bd5b037ade59a67c/src/fsharp/lexhelp.fsi#L75

@forki
Copy link
Contributor

forki commented Mar 5, 2018

@nosami
Copy link
Contributor

nosami commented Mar 5, 2018

@jwosty @forki keyword intellisense and syntax highlighting doesn't come from FCS in VS for Mac. It needs to be done separately from any work that is done here. I can add it though once this PR lands.

@forki
Copy link
Contributor

forki commented Mar 5, 2018

@nosami ideally you should change it to FCS :P

@jwosty
Copy link
Contributor Author

jwosty commented Apr 2, 2018

@dotnet-bot test this please

@Thorium
Copy link
Contributor

Thorium commented Apr 17, 2018

Nice!
Just one question: Why this is match! and not with!?

@abelbraaksma
Copy link
Contributor

abelbraaksma commented Apr 17, 2018

Just one question: Why this is match! and not with!?

@Thorium, that seems just logical to me. I mean, the keyword with has multiple meanings (type extensions, copy-and-update record expressions, object expressions, match expressions), the keyword match doesn't. Using match! instead of with! keeps things simple and clear.

Might be interesting to consider function! though, as it is often used as shorthand for match. Though I'm not sure about the particulars.

But apparently I repeat myself and there's already an answer to that from @jwosty:

As for function!, I feel that would have to be another feature suggestion at this point. [...] Also, the semantics of that would warrant a discussion [...]

@jwosty
Copy link
Contributor Author

jwosty commented Apr 17, 2018

@Thorium Because match! looks similar to the other CE constructs; the "bang" always comes before the element that you're binding, never after. To me, this:

let! x = expr1
match! expr2 with
| ...

looks more consistent, and thus more visually pleasing, than this:

let! x = expr1
match expr2 with!
| ...

@abelbraaksma I agree, it would be interesting to discuss that -- you should consider starting an fslang-suggestions thread

@Thorium
Copy link
Contributor

Thorium commented Apr 17, 2018

@jwosty I was thinking of

match expr2 with!
| ...

similarity of what could be

try expr2 with!
| ...

when there is also a finally!

@forki
Copy link
Contributor

forki commented Apr 17, 2018 via email

@PatrickMcDonald
Copy link
Contributor

As Yoda might say:

do or !do, there is no try

@cartermp cartermp added this to the 15.8 milestone May 20, 2018
@dsyme
Copy link
Contributor

dsyme commented May 21, 2018

@jwosty Could you merge with master? thanks

@cartermp
Copy link
Contributor

Something is off here, there are far too many changes getting merged in

@jwosty
Copy link
Contributor Author

jwosty commented May 21, 2018

@cartermp Ah, that's because I did a squash merge. I should probably roll it back and redo it without squashing. My bad.

For cleaner history, I'm gonna force push to delete the merge commit

@jwosty
Copy link
Contributor Author

jwosty commented May 21, 2018

@dsyme Merged.

@forki
Copy link
Contributor

forki commented May 22, 2018 via email

@jwosty
Copy link
Contributor Author

jwosty commented May 22, 2018

@forki I mean, I've literally written multiple instances today that need it! I cannot wait to be spoiled by this addition.

@KevinRansom KevinRansom merged commit e33831a into dotnet:master May 25, 2018
@KevinRansom
Copy link
Member

Thank you for this.

@jwosty
Copy link
Contributor Author

jwosty commented May 25, 2018

@KevinRansom of course! Glad to help F# move forward.

@forki
Copy link
Contributor

forki commented May 25, 2018 via email

type CardSuit = | Hearts | Diamonds | Clubs | Spades
let fetchSuit () = async {
// do something in order to not allow optimizing things away
Async.Sleep 1
Copy link
Contributor Author

@jwosty jwosty Jul 30, 2018

Choose a reason for hiding this comment

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

Just noticed -- it should be do! Async.Sleep 1.

On second thought I'm not sure this is needed at all -- the compiler can't doesn't really optimize let foo () = async { return 42 }, does it?

@jwosty jwosty deleted the match-bang branch May 22, 2020 23:07
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.