Thread overview
May 29

Today I woke up and found I wanted to write up a proposal for pattern matching for D.

I had been putting this one off as it wasn't really of interest to me and wanted to see what Walter had come up with for last DConf Online (it was changed at last minute).

As a feature it seems fairly straightforward; we as a community want a context-aware keyword called match that operates on a type or a tuple and performs matching with support for multiple dispatch and inference of pattern types. Without full pattern matching of literals or nested types.

This will work for sum types without the need to add them to the language beforehand.

Permanent: https://gist.github.com/rikkimax/79cbe199618b3f99104f7df2fc2a9681/e0e6dd44f7477be962e6c71312ba08a1fe1ee8d6
Latest: https://gist.github.com/rikkimax/79cbe199618b3f99104f7df2fc2a9681

alias MTU = MyTaggedUnion!(int, float, string);

MTU mtu = MTU(1.5);

mtu.match {
	(float v) => writeln("a float! ", v),
	v => writeln("catch all! ", v)
};
May 29

On Wednesday, 29 May 2024 at 18:24:19 UTC, Richard (Rikki) Andrew Cattermole wrote:

>
alias MTU = MyTaggedUnion!(int, float, string);

MTU mtu = MTU(1.5);

mtu.match {
	(float v) => writeln("a float! ", v),
	v => writeln("catch all! ", v)
};

why not
(auto v)
for syntax consistency?

May 30
On 30/05/2024 6:33 AM, Daniel N wrote:
> On Wednesday, 29 May 2024 at 18:24:19 UTC, Richard (Rikki) Andrew Cattermole wrote:
>> ```d
>> alias MTU = MyTaggedUnion!(int, float, string);
>>
>> MTU mtu = MTU(1.5);
>>
>> mtu.match {
>>     (float v) => writeln("a float! ", v),
>>     v => writeln("catch all! ", v)
>> };
>> ```
> 
> why not
> (auto v)
> for syntax consistency?

It already is consistent for syntax.

```d
// Use a catch-all handler to give a default result.
bool isFahrenheit(Temperature t)
{
    return t.match!(
        (Fahrenheit f) => true,
        _ => false
    );
}
```

https://dlang.org/phobos/std_sumtype.html
May 29

On Wednesday, 29 May 2024 at 18:24:19 UTC, Richard (Rikki) Andrew Cattermole wrote:

>

Today I woke up and found I wanted to write up a proposal for pattern matching for D.

hmmm strange

>

I had been putting this one off as it wasn't really of interest to me and wanted to see what Walter had come up with for last DConf Online (it was changed at last minute).

As a feature it seems fairly straightforward; we as a community want a context-aware keyword called match that operates on a type or a tuple and performs matching with support for multiple dispatch and inference of pattern types. Without full pattern matching of literals or nested types.

This will work for sum types without the need to add them to the language beforehand.

Permanent: https://gist.github.com/rikkimax/79cbe199618b3f99104f7df2fc2a9681/e0e6dd44f7477be962e6c71312ba08a1fe1ee8d6
Latest: https://gist.github.com/rikkimax/79cbe199618b3f99104f7df2fc2a9681

alias MTU = MyTaggedUnion!(int, float, string);

MTU mtu = MTU(1.5);

mtu.match {
	(float v) => writeln("a float! ", v),
	v => writeln("catch all! ", v)
};

I see no obvious way "value specialization" would work here

May 30
On 30/05/2024 6:48 AM, monkyyy wrote:
> On Wednesday, 29 May 2024 at 18:24:19 UTC, Richard (Rikki) Andrew Cattermole wrote:
>> Today I woke up and found I wanted to write up a proposal for pattern matching for D.
> 
> hmmm strange

I know right.

Last time this happened I wrote 6500 words in four days.

>> I had been putting this one off as it wasn't really of interest to me and wanted to see what Walter had come up with for last DConf Online (it was changed at last minute).
>>
>> As a feature it seems fairly straightforward; we as a community want a context-aware keyword called ``match`` that operates on a type or a tuple and performs matching with support for multiple dispatch and inference of pattern types. Without full pattern matching of literals or nested types.
>>
>> This will work for sum types without the need to add them to the language beforehand.
>>
>> Permanent: https://gist.github.com/rikkimax/79cbe199618b3f99104f7df2fc2a9681/e0e6dd44f7477be962e6c71312ba08a1fe1ee8d6
>> Latest: https://gist.github.com/rikkimax/79cbe199618b3f99104f7df2fc2a9681
>>
>> ```d
>> alias MTU = MyTaggedUnion!(int, float, string);
>>
>> MTU mtu = MTU(1.5);
>>
>> mtu.match {
>>     (float v) => writeln("a float! ", v),
>>     v => writeln("catch all! ", v)
>> };
>> ```
> 
> I see no obvious way "value specialization" would work here

Indeed.

It would be good to make sure we're not painting ourselves in a corner for such language features. So if others who care about it can figure it out, that'll be great.

May 29

On Wednesday, 29 May 2024 at 18:24:19 UTC, Richard (Rikki) Andrew Cattermole wrote:

>

Today I woke up and found I wanted to write up a proposal for pattern matching for D.

Permanent: https://gist.github.com/rikkimax/79cbe199618b3f99104f7df2fc2a9681/e0e6dd44f7477be962e6c71312ba08a1fe1ee8d6
Latest: https://gist.github.com/rikkimax/79cbe199618b3f99104f7df2fc2a9681

>

A __tag member must evaluate to an integer

Does this mean __tag can also be a member-function? For types where the tag doesn't need any storage (like NaN-boxing, disjoint enums, etc.).

I think it would be nice if the match-patterns were semicolon delimited, so that static if and static foreach and whatnot could be used in a match block—something like:

mtu1.match {
	static if (condition) {
		(float v) => writeln("a float! ", v);
	}

	static foreach (T; Types) {
		(T v) => writeln(T.stringof, " ", v);
	}

	v => writeln("catch all! ", v);
}
May 29
On Wednesday, 29 May 2024 at 19:10:33 UTC, Richard (Rikki) Andrew Cattermole wrote:
>
>> I see no obvious way "value specialization" would work here
>
> Indeed.
>
> It would be good to make sure we're not painting ourselves in a corner for such language features. So if others who care about it can figure it out, that'll be great.

I care far more about value specialization then type untangling of sumtypes

functional pattern matching maybe use types more, but we dont need monads or nullable thats a composition of null and a type I can use a bool instead of a abstract null that falls out of some math theory

How would this help, lets say a networking dummy program, with 5 http error codes to checks, usernames, and passwords? That would probaly be a good example of ifelse hell
May 30
On 30/05/2024 7:38 AM, Harry Gillanders wrote:
> On Wednesday, 29 May 2024 at 18:24:19 UTC, Richard (Rikki) Andrew Cattermole wrote:
>> Today I woke up and found I wanted to write up a proposal for pattern matching for D.
>>
>> Permanent: https://gist.github.com/rikkimax/79cbe199618b3f99104f7df2fc2a9681/e0e6dd44f7477be962e6c71312ba08a1fe1ee8d6
>> Latest: https://gist.github.com/rikkimax/79cbe199618b3f99104f7df2fc2a9681
> 
> 
>> A __tag member must evaluate to an integer
> 
> Does this mean `__tag` can also be a member-function? For types where the tag doesn't need any storage (like NaN-boxing, disjoint enums, etc.).

Yes. You would want this to protect your tag value so that it would be read only.

> I think it would be nice if the match-patterns were semicolon delimited, so that `static if` and `static foreach` and whatnot could be used in a `match` block—something like:
> 
> ```d
> mtu1.match {
>      static if (condition) {
>          (float v) => writeln("a float! ", v);
>      }
> 
>      static foreach (T; Types) {
>          (T v) => writeln(T.stringof, " ", v);
>      }
> 
>      v => writeln("catch all! ", v);
> }
> ```

That could be a good reason to switch.

Although it can be done using a fallback ``(arg) { ... },`` instead.