Option types and pattern matching.

TheFlyingFiddle via Digitalmars-d digitalmars-d at puremagic.com
Mon Oct 26 07:13:19 PDT 2015


On Monday, 26 October 2015 at 11:40:09 UTC, Edmund Smith wrote:
> On Sunday, 25 October 2015 at 06:22:51 UTC, TheFlyingFiddle 
> wrote:
> You could also emulate constant matching using default 
> parameters (albeit with the restriction that they must be after 
> any non-default/constant parameters), since the defaults form 
> part of the function's type. I tried making something like this 
> earlier this summer and it'd check that a given value was first 
> equal to the default parameter and match if so, or match if 
> there was no default parameter but the types matched.
>
> e.g.
> //template ma(tch/g)ic
>
> unittest
> {
>     Algebraic!(string, int, double, MyStruct) v = 5;
>     string s = v.match!(
>         (string s = "") => "Empty string!",
>         (string s) => s,
>         (int i = 7) => "Lucky number 7",
>         (int i = 0) => "Nil",
>         (int i) => i.to!string,
>         (double d) => d.to!string,
>         (MyStruct m = MyStruct(15)) => "Special MyStruct value",
>         (MyStruct m) => m.name, //
>         () => "ooer");
>     writeln(s);
> }
>
> It's a bit ugly overloading language features like this, but it 
> makes the syntax a little prettier.
This does look nicer indeed.

>>Why not just use a value as an extra argument:
>>v.match!(
>>    7, (int i) => "Lucky number 7"
>>);
I like this you could go further with this to allow any number of 
constants.
v.match!(
     5, 7,   i => "Was: " ~ i.to!string,
     (int i)   => "Was this: " ~ i.to!string);

Or for ranges.
v.match!(
     MatchR!(1, 10), i => "Was: " ~ i.to!string, //Matches 1 .. 10
     (int i)          => "Was this: " ~ i.to!string);

> I'd really like to see proper pattern matching as a 
> language-level feature however; for all the emulating it we can 
> do in D, it's not very pretty or friendly and optimising it is 
> harder since the language has no concept of pattern matching.
One could probably get something like this:

int i = 5;
string s = i.match!(
    5, 7, n => "Five or seven",
    MatchR!(10, 100), n => "Was between ten and a hundred",
    (n)     => "Was: " ~ n.to!string);

to fold into something like this:

void match(T...)(int i)
{
    switch(i)
    {
       case 5: case 7: return (T[2])!int(i);
       case 10: .. case 99: return (T[3])!int(i);
       default: return (T[4])!int(i);
    }
}

int i = 5;
string s = match!(/* lambdas and whatnot */), i);

With some template/ctfe and string mixings magic.

In-lining, constant folding etc could probably just reduce it to
the equvalent of:

int i    = 5;
string s = "Five or seven";

(if there is really good constant folding :P)

It might however generate lot's of useless symbols in the 
resulting code
making code size's larger.

> Things like Option (and other ADTs) are lovely, but really need 
> good pattern matching to become worthwhile IMO (e.g. Java 
> Optional<T> has a get() method that throws on empty, which 
> undermines the main reason to use optional -
Another thing that has always bothered me with Optional<T> in 
Java in addition to this is that the optional value itself might 
be null. So to write robust code you first have to check against 
null on the option value :P.

> Scala's Option is really nice on the other hand since you 
> can/should pattern match).
Don't really see a point in an optional type if can access the 
underlying
value without first checking if it's there.






More information about the Digitalmars-d mailing list