www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Pattern matching in C++ and D

reply Francesco Mecca <me francescomecca.eu> writes:
I found a paper regarding a proposal for pattern matching in C++ 
on HN a few days ago:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1371r1.pdf

Given the time I spent with OCaml and the OCaml compiler recently 
I find that pattern matching is an essential feature for a modern 
language and that there are cases in which the pattern matching 
compiler outputs better code than nested handwritten if-else-if's.

In D we have the Sumtype library that is an excellent library for 
sumtypes and coincidentally provides pattern matching based on 
the type of the value being matched.

As outlined from the paper there are many other kinds of pattern 
that could be very useful in current D code. I won't make 
examples here because the paper is full of examples that are 
pretty easy to mentally translate from C++ to D.

In the "Design Decision" chapter of the paper the authors discuss 
about not restricting side effects. In OCaml there are the same 
problems with guards that could have side effects. Example:

```
let function_with_side_effects x = ...
let match x = match x with
     | p1 -> e1
     | p2 when function_with_side_effects x -> e2
     | _ -> e3
```

If x is modified by functions with side effects the pattern 
matching could be not exhaustive and in the worst case the result 
undefined. The same applies when a guard uses boolean comparison 
that has been overridden by the developer.

In D we can do better than that by forcing guard expressions to 
be pure.
I also believe that ranges provides a better interface for a more 
expressive pattern matching but I have to think more about that 
(the paper shortly discuss that in section 10.2).

The main shortcoming with D is that we don't have a builtin tuple 
type and destructoring assignments.
Timon Gehr was working on that 
(https://github.com/tgehr/DIPs/blob/tuple-syntax/DIPs/DIP1xxx-tg.md) but the
last commit is 2 years old.
Jan 07 2020
next sibling parent reply IGotD- <nise nise.com> writes:
On Tuesday, 7 January 2020 at 14:00:01 UTC, Francesco Mecca wrote:
 I found a paper regarding a proposal for pattern matching in 
 C++ on HN a few days ago:
 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1371r1.pdf

 ```
 let function_with_side_effects x = ...
 let match x = match x with
     | p1 -> e1
     | p2 when function_with_side_effects x -> e2
     | _ -> e3
 ```
Doesn't the real benefit first kick in when the statement is an expression always returning a value like in your example? Neither C++ or D has that.
Jan 07 2020
parent reply Francesco Mecca <me francescomecca.eu> writes:
On Tuesday, 7 January 2020 at 17:06:30 UTC, IGotD- wrote:
 On Tuesday, 7 January 2020 at 14:00:01 UTC, Francesco Mecca 
 wrote:
 I found a paper regarding a proposal for pattern matching in 
 C++ on HN a few days ago:
 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1371r1.pdf

 ```
 let function_with_side_effects x = ...
 let match x = match x with
     | p1 -> e1
     | p2 when function_with_side_effects x -> e2
     | _ -> e3
 ```
Doesn't the real benefit first kick in when the statement is an expression always returning a value like in your example? Neither C++ or D has that.
Yes, but that should be possibile in D, isn't it?
Jan 08 2020
parent Jacob Carlborg <doob me.com> writes:
On 2020-01-08 13:12, Francesco Mecca wrote:

 Yes, but that should be possibile in D, isn't it?
Yeah, there's nothing stopping this to be implemented as an expression (I hope). -- /Jacob Carlborg
Jan 11 2020
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 07.01.20 15:00, Francesco Mecca wrote:
 
 The main shortcoming with D is that we don't have a builtin tuple type 
 and destructoring assignments.
 Timon Gehr was working on that 
 (https://github.com/tgehr/DIPs/blob/tuple-syntax/DIPs/DIP1xxx-tg.md) but 
 the last commit is 2 years old.
Partial implementation: https://github.com/dlang/dmd/compare/master...tgehr:tuple-syntax
Jan 07 2020
parent 12345swordy <alexanderheistermann gmail.com> writes:
On Tuesday, 7 January 2020 at 18:01:27 UTC, Timon Gehr wrote:
 On 07.01.20 15:00, Francesco Mecca wrote:
 
 The main shortcoming with D is that we don't have a builtin 
 tuple type and destructoring assignments.
 Timon Gehr was working on that 
 (https://github.com/tgehr/DIPs/blob/tuple-syntax/DIPs/DIP1xxx-tg.md) but the
last commit is 2 years old.
Partial implementation: https://github.com/dlang/dmd/compare/master...tgehr:tuple-syntax
IRC you don't need to have an implementation ready for a dip to be accepted, so why haven't you submit one already?
Jan 07 2020
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2020-01-07 15:00, Francesco Mecca wrote:
 I found a paper regarding a proposal for pattern matching in C++ on HN a 
 few days ago:
 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1371r1.pdf
 
 Given the time I spent with OCaml and the OCaml compiler recently I find 
 that pattern matching is an essential feature for a modern language and 
 that there are cases in which the pattern matching compiler outputs 
 better code than nested handwritten if-else-if's.
 
 In D we have the Sumtype library that is an excellent library for 
 sumtypes and coincidentally provides pattern matching based on the type 
 of the value being matched.
 
 As outlined from the paper there are many other kinds of pattern that 
 could be very useful in current D code. I won't make examples here 
 because the paper is full of examples that are pretty easy to mentally 
 translate from C++ to D.
 
 In the "Design Decision" chapter of the paper the authors discuss about 
 not restricting side effects. In OCaml there are the same problems with 
 guards that could have side effects. Example:
 
 ```
 let function_with_side_effects x = ...
 let match x = match x with
      | p1 -> e1
      | p2 when function_with_side_effects x -> e2
      | _ -> e3
 ```
 
 If x is modified by functions with side effects the pattern matching 
 could be not exhaustive and in the worst case the result undefined. The 
 same applies when a guard uses boolean comparison that has been 
 overridden by the developer.
 
 In D we can do better than that by forcing guard expressions to be pure.
 I also believe that ranges provides a better interface for a more 
 expressive pattern matching but I have to think more about that (the 
 paper shortly discuss that in section 10.2).
I would like to see pattern matching in D as well. I tried to implement a library version but hit some limitations in the language.
 The main shortcoming with D is that we don't have a builtin tuple type 
 and destructoring assignments.
 Timon Gehr was working on that 
 (https://github.com/tgehr/DIPs/blob/tuple-syntax/DIPs/DIP1xxx-tg.md) but 
 the last commit is 2 years old.
I don't see how this is a problem. Pattern matching in D would support the features that D supports. I mean, most functional languages have built-in support for lists. I don't think anyone would suggested to add support for built-in lists in D, just to be able to implement pattern matching. Just the same way as Scala supports pattern matching of classes, yet most functional languages don't, because they don't support classes in other parts of the language. -- /Jacob Carlborg
Jan 11 2020