Re: Pattern matching in D?

2016-11-02 Thread Nick Treleaven via Digitalmars-d

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


Re: Pattern matching in D?

2016-10-28 Thread Dennis Ritchie via Digitalmars-d
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


Re: Pattern matching in D?

2016-10-28 Thread Nick Treleaven via Digitalmars-d

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);
}



Re: Pattern matching in D?

2016-10-23 Thread Nick Sabalausky via Digitalmars-d

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.




Re: Pattern matching in D?

2016-10-23 Thread Nick Sabalausky via Digitalmars-d

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.



Re: Pattern matching in D?

2016-10-23 Thread Chris M via Digitalmars-d

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.


Re: Pattern matching in D?

2016-10-21 Thread Nick Sabalausky via Digitalmars-d

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



Re: Pattern matching in D?

2016-10-21 Thread Dennis Ritchie via Digitalmars-d

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)


Re: Pattern matching in D?

2016-10-21 Thread default0 via Digitalmars-d

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)


Re: Pattern matching in D?

2016-10-21 Thread Mark via Digitalmars-d

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?


Re: Pattern matching in D?

2016-10-21 Thread ArturG via Digitalmars-d

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


Re: Pattern matching in D?

2016-10-21 Thread mogu via Digitalmars-d

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.


Re: Pattern matching in D?

2016-10-21 Thread Stefan Koch via Digitalmars-d

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" ?


Pattern matching in D?

2016-10-21 Thread Chris M. via Digitalmars-d
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?





Re: Pattern matching in D?

2016-10-21 Thread Dennis Ritchie via Digitalmars-d

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/mhdcpnnydgspxllis...@forum.dlang.org
http://forum.dlang.org/post/znfrdjkpxtixiydxp...@forum.dlang.org
http://forum.dlang.org/post/ugiypegvtdhhvzrmf...@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


Re: Pattern matching in D?

2016-10-21 Thread Chris M. via Digitalmars-d

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


Re: Pattern matching in D?

2016-10-21 Thread Dennis Ritchie via Digitalmars-d

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


Re: Emulation macros and pattern matching on D

2015-06-05 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/5/15 10:15 AM, Dennis Ritchie wrote:

On Friday, 5 June 2015 at 13:13:15 UTC, Steven Schveighoffer wrote:

string foo(string mode, string value)
{
   return `writefln(mode ` ~ mode ~ `: %s, ` ~ value ~ `);`;
}

void main()
{
   mixin(foo(Y, 3));
   mixin(foo(X, 2));
}


Thanks. It looks really simple, but I still do not understand the
concept of using mixins in full.

I do not understand why in this line:
return `writefln(mode ` ~ mode ~ `: %s, ` ~ value ~ `);`;

use the following syntax:
~ mode ~ , ~ value ~


Because what foo is constructing is a string that makes sense in the 
*caller*, not inside foo. What those statements do is concat the *value* 
of mode (i.e. Y or X) and the *value* of value (i.e. 3 or 2) to 
the string.


It's equivalent to rust using the ${e} to do variable substitution.


For example, why here I can simply write:

void main() {
 int b = 5;
 mixin(`int a = b;`);
 assert(a == 5);
}


Because b makes sense in the context of main.


Why should not I write like this:

void main() {
 int b = 5;
 mixin(`int a =  ` ~ b ~ ` ;`);
 assert(a == 5);
}


Because it won't compile :) Mixin strings must be constructable at 
compile time, the value of b depends on runtime. Not to mention that you 
can't concat strings with ints.


-Steve


Re: Pattern matching in D

2010-03-08 Thread retard
Sun, 07 Mar 2010 22:05:19 -0800, Walter Bright wrote:

 BCS wrote:
 I think what retard was asking was what types are legal as the argument
 for a switch?
 
 IIRC the list is: all the arithmetic types and the string types.
 
 The value pattern matching that is being asked for would allow just
 about anything that has a compile time literal syntax:
 
 void fn(int[] ar)
 {
   switch(ar)
   {
  case [1,2,3]: ... break;
  case [1,2,4]: ... break;
  case [1,3,2]: ... break;
   }
 
 }
 
 I've thought more than once about adding that, but it just seems
 pointless. I've never run into a use case for it. If you do run into
 one,
 
  if (ar == [1,2,3]) ...
  else if (ar == [1,2,4]) ...
  else if (ar == [1,3,2]) ...
 
 will work just fine.

The same can be said about matching integer values:

  if (ar == 1) ...
  else if (ar == 2) ...
  else if (ar == 3) ...

I guess the point is just to unify many kinds of cases.

class Foo
class Bar : Foo { void doBarMethod() {} }
class Bar2 : Foo { void doBar2Method() {} }

if (cast(Bar)foo)
  (cast(Bar)foo).doBarMethod();
else if (cast(Bar2)foo)
  (cast(Bar2)foo).doBar2Method();
else
  writefln(Oh no!)

foo match {
  case b: Bar = b.doBarMethod
  case b: Bar2 = b.doBar2Method
  case _ = println(Oh no!)
}

(1, (1,2)) match {
  case (1, (1, _)) = println(nice tuple)
  case _ =
}

def main(args: Array[Byte]) =
  args(0) match {
case -help = println(Usage: ...)
case -moo = println(moo)
  }


Re: Pattern matching in D

2010-03-08 Thread Walter Bright

retard wrote:

I've thought more than once about adding that, but it just seems
pointless. I've never run into a use case for it. If you do run into
one,

 if (ar == [1,2,3]) ...
 else if (ar == [1,2,4]) ...
 else if (ar == [1,3,2]) ...

will work just fine.


The same can be said about matching integer values:


 if (ar == 1) ...
 else if (ar == 2) ...
 else if (ar == 3) ...


I don't agree, because switching on integer values is commonplace, and 
switching on array literals pretty much never happens.


(Note: switching on floating point values is worse than useless, as 
floating point computations rarely produce exact results, and supporting 
such a capability will give a false sense that it should work.)




I guess the point is just to unify many kinds of cases.

class Foo
class Bar : Foo { void doBarMethod() {} }
class Bar2 : Foo { void doBar2Method() {} }

if (cast(Bar)foo)
  (cast(Bar)foo).doBarMethod();
else if (cast(Bar2)foo)
  (cast(Bar2)foo).doBar2Method();
else
  writefln(Oh no!)



I have to say, if you find code written that way, you're doing OOP wrong.



foo match {
  case b: Bar = b.doBarMethod
  case b: Bar2 = b.doBar2Method
  case _ = println(Oh no!)
}

(1, (1,2)) match {
  case (1, (1, _)) = println(nice tuple)
  case _ =
}

def main(args: Array[Byte]) =
  args(0) match {
case -help = println(Usage: ...)
case -moo = println(moo)
  }


D already supports string switches.


Re: Pattern matching in D

2010-03-08 Thread retard
Mon, 08 Mar 2010 03:35:56 -0800, Walter Bright wrote:

 retard wrote:
 I've thought more than once about adding that, but it just seems
 pointless. I've never run into a use case for it. If you do run into
 one,

  if (ar == [1,2,3]) ...
  else if (ar == [1,2,4]) ...
  else if (ar == [1,3,2]) ...

 will work just fine.
 
 The same can be said about matching integer values:
 
  if (ar == 1) ...
  else if (ar == 2) ...
  else if (ar == 3) ...
 
 I don't agree, because switching on integer values is commonplace, and
 switching on array literals pretty much never happens.
 
 (Note: switching on floating point values is worse than useless, as
 floating point computations rarely produce exact results, and supporting
 such a capability will give a false sense that it should work.)
 
 
 I guess the point is just to unify many kinds of cases.
 
 class Foo
 class Bar : Foo { void doBarMethod() {} } class Bar2 : Foo { void
 doBar2Method() {} }
 
 if (cast(Bar)foo)
   (cast(Bar)foo).doBarMethod();
 else if (cast(Bar2)foo)
   (cast(Bar2)foo).doBar2Method();
 else
   writefln(Oh no!)
 
 
 I have to say, if you find code written that way, you're doing OOP
 wrong.

The correct solution, multimethods or the visitor pattern, is sometimes 
very expensive. They become very verbose when compared to simple pattern 
matching:

 foo match {
   case b: Bar = b.doBarMethod
   case b: Bar2 = b.doBar2Method
   case _ = println(Oh no!)
 }

The OOP argument is false here. Sometimes OOP isn't the best way to 
describe declarative data. It surely allows you to implement this, but 
the cost is a much larger verbosity.

The data type might be just a simple tagged union (in which case powerful 
optimizations can be used). Instead of writing

 enum node_type { sum_node, mul_node, ... }

 struct tree {
   node_type type;

   union {
// bla bla
   }
 }

you can automatically eliminate the boilerplate code with this higher 
level construct. It's also much safer - unions are known to be a security 
loophole when used carelessly. Also with instanceof/cast() you may need 
to cast twice unlike in the match expression above.

 
 (1, (1,2)) match {
   case (1, (1, _)) = println(nice tuple) case _ =
 }
 
 def main(args: Array[Byte]) =
   args(0) match {
 case -help = println(Usage: ...) case -moo = println(moo)
   }
 
 D already supports string switches.

I know that. The idea was to show how general pattern matching unifies 
the instanceof construct, integer switches, string switches and various 
kinds of algebraic data type manipulation such as tree/graph rewriting.

It's a much more generalized construct in all possible ways - and very 
intuitive to use. Some of the beauty is lost when you read the example 
written in Scala, but e.g. in Haskell the pattern matching closely 
reflects the structure of the algebraic data type.


Re: Pattern matching in D

2010-03-08 Thread Simen kjaeraas

Walter Bright newshou...@digitalmars.com wrote:


foo match {
  case b: Bar = b.doBarMethod
  case b: Bar2 = b.doBar2Method
  case _ = println(Oh no!)
}
 (1, (1,2)) match {
  case (1, (1, _)) = println(nice tuple)
  case _ =
}
 def main(args: Array[Byte]) =
  args(0) match {
case -help = println(Usage: ...)
case -moo = println(moo)
  }


D already supports string switches.


Which means that D supports array switches (untested code):

switch( (string)foo ) {
  case (string)[1,2,3]: doSomething( );
  case (string)[3,2,1]: doSomethingElse( );
}

Might require some tweaking, but I believe this would work. Not saying  
it's a good idea, though.


As for structs:

switch ( foo.toHash( ) ) {
  case S(1,2,3).toHash( ): doSomething( );
  case S(3,2,1).toHash( ): doSomethingElse( );
}

If toHash is CTFE-able. Just as untested, and might not work at all.

--
Simen


Re: Pattern matching in D

2010-03-08 Thread BCS

Hello Walter,



(Note: switching on floating point values is worse than useless, as
floating point computations rarely produce exact results, and
supporting such a capability will give a false sense that it should
work.)



What about allowing switch on FP but only allowing CaseRangeStatements?

--
... IXOYE





Re: Pattern matching in D

2010-03-08 Thread Walter Bright

BCS wrote:

What about allowing switch on FP but only allowing CaseRangeStatements?


Is there really a compelling use case for that?

I really think we need to focus on what is needed to be done, not what 
can be done. Otherwise we wind up with a huge boatload of features yet 
have an unuseful language.


Pattern matching in D

2010-03-07 Thread Walter Bright

retard wrote:

Sun, 07 Mar 2010 11:17:46 -0800, Walter Bright wrote:


retard wrote:

- Pattern matching (extension to enum/string/integer accepting switch)

Andrei and Sean have shown how to do that nicely with existing language
features.


Really? I'd really like to see how this is done.



foo(  v,
 (int i) { writeln(I saw an int , i); },
 (string s) { writeln(I saw a string , s); ),
 (Variant any) { writeln(I saw the default case , any); }
   );


foo is a variadic template which takes its first argument, v, and 
attempts to match it with each delegate in turn. The first one that 
matches is executed.


The matching is all done at compile time, of course, and the delegate 
can be inlined.


Re: Pattern matching in D

2010-03-07 Thread BCS

Hello Walter,


retard wrote:


Sun, 07 Mar 2010 11:17:46 -0800, Walter Bright wrote:


retard wrote:


- Pattern matching (extension to enum/string/integer accepting
switch)


Andrei and Sean have shown how to do that nicely with existing
language features.


Really? I'd really like to see how this is done.


foo is a variadic template which takes its first argument, v, and
attempts to match it with each delegate in turn. The first one that
matches is executed.

The matching is all done at compile time, of course, and the delegate
can be inlined.



I think (from context in other strands) that the OP was referring to value, 
not type, pattern matching.





--
... IXOYE





Re: Pattern matching in D

2010-03-07 Thread Walter Bright

BCS wrote:
I think (from context in other strands) that the OP was referring to 
value, not type, pattern matching.


Value pattern matching is just a regular switch statement.


Re: Pattern matching in D

2010-03-07 Thread retard
Sun, 07 Mar 2010 15:38:07 -0800, Walter Bright wrote:

 retard wrote:
 Sun, 07 Mar 2010 11:17:46 -0800, Walter Bright wrote:
 
 retard wrote:
 - Pattern matching (extension to enum/string/integer accepting
 switch)
 Andrei and Sean have shown how to do that nicely with existing
 language features.
 
 Really? I'd really like to see how this is done.
 
 
 foo(  v,
   (int i) { writeln(I saw an int , i); }, (string s) { writeln(I
   saw a string , s); ), (Variant any) { writeln(I saw the default
   case , any); }
 );
 
 
 foo is a variadic template which takes its first argument, v, and
 attempts to match it with each delegate in turn. The first one that
 matches is executed.

Ok, that's pretty good.

Now let's see how the pattern matching in Scala works:

val a = 42

val b = 123

// basic matching of values
a match {
  case 1 = println(You gave 1)
  case 2 = // functionality for 2
  case _ = println(The default case)
}

// matching  refs to symbols
a match {
  case `b` = println(You gave 123-1=122)
  case b = println(You gave  + b)
}

trait Spiny
class Animal
class Rabbit extends Animal
class Hedgehog extends Animal with Spiny
class Bear extends Animal
object Roger extends Rabbit
object Yogi extends Bear

// matching  subtyping
def foo(a:Animal) = a match {
  case Roger = guess who framed you?
  case Yogi = o hai
  case h: Animal with Spiny = Possibly a hedgehog
  case _ = Giving up
}

// nested matches
{ case a :: b :: c = 1 }: (List[Int] = Int)

class Expr
case class Value[T](v: T) extends Expr
case class SumExpr(l: Expr, r: Expr) extends Expr
case class MulExpr(l: Expr, r: Expr) extends Expr
case class NegExpr(e: Expr) extends Expr

def foo(e:Expr) = e match {
  case MulExpr(SumExpr(NegExpr(Value(1)), NegExpr(Value(5))), Value(2)) 
= println(Imagine, this could be used for AST processing)
  case _ = // do nothing
}

{ case htmlasome link/a/html = println(found a link inside the 
DOM) }: (scala.xml.Elem = Unit)

I left out some of the more complex functionality, e.g. extractors and 
more complex higher kinded stuff..

 
 The matching is all done at compile time, of course, and the delegate
 can be inlined.

I guess this tells a lot. No feature is added to D unless it can do 
something statically with zero runtime cost.


Re: Pattern matching in D

2010-03-07 Thread retard
Sun, 07 Mar 2010 15:59:37 -0800, Walter Bright wrote:

 BCS wrote:
 I think (from context in other strands) that the OP was referring to
 value, not type, pattern matching.
 
 Value pattern matching is just a regular switch statement.

So what types does the regular switch accept in D 2 ?


Re: Pattern matching in D

2010-03-07 Thread bearophile
retard:
 So what types does the regular switch accept in D 2 ?

It accepts all integral values, including all chars and true enums. It accepts 
strings but not arrays.

It doesn't accept floating point values, complex numbers (that are FP), 
structs, objects and associative arrays.

Eventually support for arrays and structs too can be added, someone in the D 
Wish list has asked for those two things, but so far I haven't found a need for 
this.

If D adds tagged structs, then switch can read their tag. Time ago I have 
thought about an opSwitch operator for structs/classes, that gets called by 
switch, but I haven had not enough need for something like this so far. So I 
have never asked for it.

Bye,
bearophile


Re: Pattern matching in D

2010-03-07 Thread Walter Bright

retard wrote:

Sun, 07 Mar 2010 15:59:37 -0800, Walter Bright wrote:


BCS wrote:

I think (from context in other strands) that the OP was referring to
value, not type, pattern matching.

Value pattern matching is just a regular switch statement.


So what types does the regular switch accept in D 2 ?


I already posted the way to do type pattern matching.


Re: Pattern matching in D

2010-03-07 Thread Walter Bright

retard wrote:

The matching is all done at compile time, of course, and the delegate
can be inlined.


I guess this tells a lot. No feature is added to D unless it can do 
something statically with zero runtime cost.


You did mention in another post in this thread that you were concerned 
about optimization?


Re: Pattern matching in D

2010-03-07 Thread BCS

Hello Walter,


retard wrote:


Sun, 07 Mar 2010 15:59:37 -0800, Walter Bright wrote:


BCS wrote:


I think (from context in other strands) that the OP was referring
to value, not type, pattern matching.


Value pattern matching is just a regular switch statement.


So what types does the regular switch accept in D 2 ?


I already posted the way to do type pattern matching.



I think what retard was asking was what types are legal as the argument for 
a switch?


IIRC the list is: all the arithmetic types and the string types.

The value pattern matching that is being asked for would allow just about 
anything that has a compile time literal syntax:


void fn(int[] ar)
{
  switch(ar)
  {
 case [1,2,3]: ... break;
 case [1,2,4]: ... break;
 case [1,3,2]: ... break;
  }

}

--
... IXOYE





Re: Pattern matching in D

2010-03-07 Thread Walter Bright

BCS wrote:
I think what retard was asking was what types are legal as the argument 
for a switch?


IIRC the list is: all the arithmetic types and the string types.

The value pattern matching that is being asked for would allow just 
about anything that has a compile time literal syntax:


void fn(int[] ar)
{
  switch(ar)
  {
 case [1,2,3]: ... break;
 case [1,2,4]: ... break;
 case [1,3,2]: ... break;
  }

}


I've thought more than once about adding that, but it just seems 
pointless. I've never run into a use case for it. If you do run into one,


if (ar == [1,2,3]) ...
else if (ar == [1,2,4]) ...
else if (ar == [1,3,2]) ...

will work just fine.