www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Pattern matching in D?

reply Chris M. <chrismohrfeld comcast.net> writes:
So I know you can do some pattern matching with templates in D, 
but has there been any discussion about implementing it as a 
language feature, maybe something similar to Rust's match keyword 
(https://doc.rust-lang.org/stable/book/patterns.html)? What would 
your guys' thoughts be?
Oct 20 2016
next sibling parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Friday, 21 October 2016 at 02:16:44 UTC, Chris M. wrote:
 So I know you can do some pattern matching with templates in D, 
 but has there been any discussion about implementing it as a 
 language feature, maybe something similar to Rust's match 
 keyword (https://doc.rust-lang.org/stable/book/patterns.html)? 
 What would your guys' thoughts be?
How is this diffrent from "switch-case" ?
Oct 20 2016
next sibling parent Dennis Ritchie <dennis.ritchie mail.ru> writes:
On Friday, 21 October 2016 at 02:40:45 UTC, Stefan Koch wrote:
 How is this diffrent from "switch-case" ?
A more laconic and convenient form of the recording conditions: * No need to constantly write "case", "break", "case", "break", ... * You can use the "|", it facilitates the matching also inside the body "match" and allows the use of multiple patterns * Works with tuples and slices * More modern than the "switch" * etc. https://doc.rust-lang.org/stable/book/slice-patterns.html https://doc.rust-lang.org/stable/book/box-syntax-and-patterns.html
Oct 20 2016
prev sibling next sibling parent Chris M. <chrismohrfeld comcast.net> writes:
On Friday, 21 October 2016 at 02:40:45 UTC, Stefan Koch wrote:
 On Friday, 21 October 2016 at 02:16:44 UTC, Chris M. wrote:
 So I know you can do some pattern matching with templates in 
 D, but has there been any discussion about implementing it as 
 a language feature, maybe something similar to Rust's match 
 keyword (https://doc.rust-lang.org/stable/book/patterns.html)? 
 What would your guys' thoughts be?
How is this diffrent from "switch-case" ?
Rust's match is more powerful than a regular switch statement. A case in a switch statement can only match one value in each case (or a range of values), whereas pattern matching can do everything Dennis described above. One important concept I'd also point out is that Rust's match statement can destructure a data type like structs or tuples, so it'll allow you to easily work with individual components of any compound data type. You can also look at how Haskell does it, it's a pretty great feature https://www.haskell.org/tutorial/patterns.html http://learnyouahaskell.com/syntax-in-functions
Oct 20 2016
prev sibling parent ArturG <var.spool.mail700 gmail.com> writes:
On Friday, 21 October 2016 at 02:40:45 UTC, Stefan Koch wrote:
 On Friday, 21 October 2016 at 02:16:44 UTC, Chris M. wrote:
 So I know you can do some pattern matching with templates in 
 D, but has there been any discussion about implementing it as 
 a language feature, maybe something similar to Rust's match 
 keyword (https://doc.rust-lang.org/stable/book/patterns.html)? 
 What would your guys' thoughts be?
How is this diffrent from "switch-case" ?
switch is a statement, rusts match is an expression and can return a value. i posted this[1] templates a while ago with which you can probably do most of what rust can do with the match expressing (not tested havent looked into rust much and pattern matching isnt the main purpose of them), by combining existing D features. e.g. 5.call!(a => a == 3? "three" : a == 5? "five" : "nomatch").writeln; prints: five 5.call!((a){ a == 3? "three".writeln : a == 5? "five".writeln : null;}).writeln; prints: five 5 [1] http://melpon.org/wandbox/permlink/ngUYhp7SS6uY283b
Oct 21 2016
prev sibling next sibling parent reply Dennis Ritchie <dennis.ritchie mail.ru> writes:
On Friday, 21 October 2016 at 02:16:44 UTC, Chris M. wrote:
 So I know you can do some pattern matching with templates in D, 
 but has there been any discussion about implementing it as a 
 language feature, maybe something similar to Rust's match 
 keyword (https://doc.rust-lang.org/stable/book/patterns.html)? 
 What would your guys' thoughts be?
On this topic there were many discussions. Here are some of them: http://forum.dlang.org/post/mhdcpnnydgspxllismlb forum.dlang.org http://forum.dlang.org/post/znfrdjkpxtixiydxpcbr forum.dlang.org http://forum.dlang.org/post/ugiypegvtdhhvzrmfuua forum.dlang.org The problem is that D is not macros, and the implementation of pattern matching without macros will not be very good. In turn, the implementation of macros in D - this is also not a good idea. Previously, there were ideas on the implementation of macros in D, but now they are no longer relevant: http://s3.amazonaws.com/dconf2007/WalterAndrei.pdf
Oct 20 2016
next sibling parent mogu <mogucpp 163.com> writes:
On Friday, 21 October 2016 at 06:50:26 UTC, Dennis Ritchie wrote:
 The problem is that D is not macros, and the implementation of 
 pattern matching without macros will not be very good. In turn, 
 the implementation of macros in D - this is also not a good 
 idea.
Agreed. D has not macro, this makes argly syntax while using mixin instead. Event C/C++ has c-macro to fix the syntax issues.
Oct 21 2016
prev sibling parent reply Mark <smarksc gmail.com> writes:
On Friday, 21 October 2016 at 06:50:26 UTC, Dennis Ritchie wrote:
 Previously, there were ideas on the implementation of macros in 
 D, but now they are no longer relevant:
 http://s3.amazonaws.com/dconf2007/WalterAndrei.pdf
AST macros are permanently off the table?
Oct 21 2016
parent reply default0 <schneider.cedric gmx.de> writes:
On Friday, 21 October 2016 at 11:49:42 UTC, Mark wrote:
 On Friday, 21 October 2016 at 06:50:26 UTC, Dennis Ritchie 
 wrote:
 Previously, there were ideas on the implementation of macros 
 in D, but now they are no longer relevant:
 http://s3.amazonaws.com/dconf2007/WalterAndrei.pdf
AST macros are permanently off the table?
Unless you find a way to convince Walter and Andrei that its not gonna result in everyone defining their own sub-language within D, making D code harder to read for others and/or have good reasons for things they enable that currently cannot be done (read: have rather ugly and laborious/error-prone workarounds or simply no workarounds at all while being desirable things to want to do). At least as far as I remember those were the main points they were on about :o)
Oct 21 2016
parent Dennis Ritchie <dennis.ritchie mail.ru> writes:
On Friday, 21 October 2016 at 12:17:30 UTC, default0 wrote:
 Unless you find a way to convince Walter and Andrei that its 
 not gonna result in everyone defining their own sub-language 
 within D, making D code harder to read for others and/or have 
 good reasons for things they enable that currently cannot be 
 done (read: have rather ugly and laborious/error-prone 
 workarounds or simply no workarounds at all while being 
 desirable things to want to do).
IMHO, the best option to do so to create an experimental D-compiler, which will support macros. And, of course, working examples, which will show all the positive benefits of D with macros. Dreams... :D)
Oct 21 2016
prev sibling next sibling parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 10/20/2016 10:16 PM, Chris M. wrote:
 So I know you can do some pattern matching with templates in D, but has
 there been any discussion about implementing it as a language feature,
 maybe something similar to Rust's match keyword
 (https://doc.rust-lang.org/stable/book/patterns.html)? What would your
 guys' thoughts be?
What I've been really wanting for a long time is the one-two combo of Nemerle's variants and pattern matching: https://github.com/rsdn/nemerle/wiki/Grok-Variants-and-matching
Oct 21 2016
parent reply Chris M <chrismohrfeld comcast.net> writes:
On Friday, 21 October 2016 at 19:00:55 UTC, Nick Sabalausky wrote:
 On 10/20/2016 10:16 PM, Chris M. wrote:
 So I know you can do some pattern matching with templates in 
 D, but has
 there been any discussion about implementing it as a language 
 feature,
 maybe something similar to Rust's match keyword
 (https://doc.rust-lang.org/stable/book/patterns.html)? What 
 would your
 guys' thoughts be?
What I've been really wanting for a long time is the one-two combo of Nemerle's variants and pattern matching: https://github.com/rsdn/nemerle/wiki/Grok-Variants-and-matching
There is std.variant, though I haven't used it much myself and don't know how well it compares. Seems like that library would provide a good basis for providing pattern matching though.
Oct 23 2016
parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 10/23/2016 03:38 PM, Chris M wrote:
 On Friday, 21 October 2016 at 19:00:55 UTC, Nick Sabalausky wrote:
 What I've been really wanting for a long time is the one-two combo of
 Nemerle's variants and pattern matching:

 https://github.com/rsdn/nemerle/wiki/Grok-Variants-and-matching
There is std.variant, though I haven't used it much myself and don't know how well it compares. Seems like that library would provide a good basis for providing pattern matching though.
This is one of those things where language support makes a big difference (like slices). Algebraic is the *closest* thing in D that compared to Nemerle's variants...But honestly, saying std.variant compares to Nemerle's variants is like saying C can do high-order functions, OOP, and has a module system. Yea, *technically* you can, but it's so clunky by comparison that you're really not getting much of the real benefit. One of the first examples on that page really highlights how it differs from D: -------------------------------- // An equivalent std.variant.Algebraic would be clunky by comparison: variant RgbColor { | Red | Yellow | Green | Different { red : float; green : float; blue : float; } } -------------------------------- string_of_color (color : RgbColor) : string { match (color) { | RgbColor.Red => "red" | RgbColor.Yellow => "yellow" | RgbColor.Green => "green" | RgbColor.Different (r, g, b) => $"rgb($r, $g, $b)" } } -------------------------------- D can get close, but it's just not so clean, wouldn't scale as well, and that really does make a difference (just like how many of D's features are argued by others to be "not that big a deal", but we know that it is because we use it and know that extra bit of polish D gives makes a big difference). And, yea, yea, Manu has a far better color color lib in D, but of course this is just an illustration of the language construct. It's one of those things (of which D really does have many - just not this one), that once you have it available and start using it, it's very liberating, and loosing it feels like having your hands tied. It's not my #1 missed feature in D, but it would be nice.
Oct 23 2016
parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 10/23/2016 11:55 PM, Nick Sabalausky wrote:
 --------------------------------
 // An equivalent std.variant.Algebraic would be clunky by comparison:
   variant RgbColor {
     | Red
     | Yellow
     | Green
     | Different {
         red : float;
         green : float;
         blue : float;
       }
   }
 --------------------------------
Just to compare to equivalent D: -------------------------------- struct RgbColor_ // Don't clutter the namepsace { struct Red {} struct Yellow {} struct Green {} struct Different { float red; float green; float blue; } } alias RgbColor = Algenraic!( RgbColor_.Red, RgbColor_.Yellow, RgbColor_.Green, RgbColor_.Different, } -------------------------------- It's just...I mean, yea, it works, and you could probably DRY it up a little with a type contructing template ("alias RgbColor = DoMagic!RgbColor_"), but...meh... And then the pattern matching end would be similarly "ehh...meh...": -------------------------------- RgbColor color = ...; auto x = color.visit( (RgbColor_.Red a) => "red", (RgbColor_.Yellow a) => "yellow", (RgbColor_.Green a) => "green", (RgbColor_.Red a) => mixin(interpolateStr!`rgb(${a.red}, ${a.green}, ${a.blue})`), ); -------------------------------- Again, technically works, but...ehh, it's like doing slices or high-order funcs in C.
Oct 23 2016
parent reply Nick Treleaven <nick geany.org> writes:
On Monday, 24 October 2016 at 04:14:52 UTC, Nick Sabalausky wrote:
 It's just...I mean, yea, it works, and you could probably DRY 
 it up a little with a type contructing template ("alias 
 RgbColor = DoMagic!RgbColor_"), but...meh...
I think the following should be better. Instead of Proxy we would have a bespoke mixin which might fix some of the workarounds below. In the unittest, using with(Color) should help, but I couldn't get that to compile (visit thinks invalid lambdas are being passed). import std.variant; struct Color { struct Custom { float red; float green; float blue; } //mixin NewTypes!`Red, Yellow, Green`; struct Red {} struct Yellow {} struct Green {} private auto impl = Algebraic!( Custom, Red, Yellow, Green)(); import std.typecons; mixin Proxy!impl; } unittest{ Color color; // assignment works but not ctor color = Color.Custom(1, 2, 3); assert(color.type == typeid(Color.Custom)); // FIXME: currently need impl auto x = color.impl.visit!( (Color.Red) => "red", (Color.Yellow) => "yellow", (Color.Green) => "green", (Color.Custom c) => ctFormat!`rgb(%s, %s, %s)`(c.red, c.green, c.blue) ); assert(x == "rgb(1, 2, 3)"); } // TODO: implement ct parsing auto ctFormat(string s, Args...)(Args args){ import std.format; return format(s, args); }
Oct 28 2016
parent Nick Treleaven <nick geany.org> writes:
On Friday, 28 October 2016 at 11:53:16 UTC, Nick Treleaven wrote:
 In the unittest, using with(Color) should help, but I couldn't 
 get that to compile (visit thinks invalid lambdas are being 
 passed).
https://issues.dlang.org/show_bug.cgi?id=16655
Nov 02 2016
prev sibling parent Dennis Ritchie <dennis.ritchie mail.ru> writes:
Someone may be, it will be interesting, in the C# 7 `switch` will 
be extended syntax for pattern matching:
https://github.com/dotnet/roslyn/blob/features/patterns/docs/features/patterns.md

Original post:
https://github.com/dotnet/roslyn/issues/206
Oct 28 2016