pattern-match on enums with macros and hxpattern

classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

pattern-match on enums with macros and hxpattern

Robin Palotai
After Nicolas told it would be possible to implement enum pattern-matching with Macro, I made an intial implementation.
You can find it at http://code.google.com/p/hxpattern/
Compiles with haxe from the latest svn (tested on 3392).

Details can be found on there (and maybe more to come about internals because it could hard to figure without knowing what's going on), but here is a little usage teaser:

Now instead of writing this:
return switch (e) {
   default: throw "error";
   case E1(f, x):
      switch (f) {
         default: throw "error";
         case F1:
            if (x < 5) x;
            else throw "error";
      }
};

You can write this:

return GSwitch.guarded(switch (e) {
   case E1(F1, x) = x < 5:
      x;
   default:
      throw "error";
});

Have fun :)
Robin


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: pattern-match on enums with macros and hxpattern

John A. De Goes

Nested pattern matching and guarding are things that should be implemented in the compiler. You shouldn't have to create workaround for crippled language features.

Also the syntax is not very intuitive. It should be:

case Foo(Bar(string), 230) if (string.length > 0): /* scala syntax - blah, blah blah */

Or maybe:

case Foo(Bar(string), 230) | (string.length > 0): /* haskell syntax - blah, blah blah */

Regards,

John A. De Goes
Twitter: @jdegoes 
LinkedIn: http://linkedin.com/in/jdegoes

On Sep 17, 2010, at 2:49 PM, Robin Palotai wrote:

After Nicolas told it would be possible to implement enum pattern-matching with Macro, I made an intial implementation.
You can find it at http://code.google.com/p/hxpattern/
Compiles with haxe from the latest svn (tested on 3392).

Details can be found on there (and maybe more to come about internals because it could hard to figure without knowing what's going on), but here is a little usage teaser:

Now instead of writing this:
return switch (e) {
   default: throw "error";
   case E1(f, x):
      switch (f) {
         default: throw "error";
         case F1:
            if (x < 5) x;
            else throw "error";
      }
};

You can write this:

return GSwitch.guarded(switch (e) {
   case E1(F1, x) = x < 5:
      x;
   default:
      throw "error";
});

Have fun :)
Robin

--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: pattern-match on enums with macros and hxpattern

Robin Palotai
Maybe - but I had easy access to the macro and don't really know the compiler enough to do it, so it's more than nothing.
About the guard delimiter, a better could be chosen. Assignment was chosen because it was accepted by Macro ("if" doesn't fit syntactically)

Robin

2010.09.17. 22:56 keltezéssel, John A. De Goes írta:

Nested pattern matching and guarding are things that should be implemented in the compiler. You shouldn't have to create workaround for crippled language features.

Also the syntax is not very intuitive. It should be:

case Foo(Bar(string), 230) if (string.length > 0): /* scala syntax - blah, blah blah */

Or maybe:

case Foo(Bar(string), 230) | (string.length > 0): /* haskell syntax - blah, blah blah */

Regards,

John A. De Goes
Twitter: @jdegoes 
LinkedIn: http://linkedin.com/in/jdegoes

On Sep 17, 2010, at 2:49 PM, Robin Palotai wrote:

After Nicolas told it would be possible to implement enum pattern-matching with Macro, I made an intial implementation.
You can find it at http://code.google.com/p/hxpattern/
Compiles with haxe from the latest svn (tested on 3392).

Details can be found on there (and maybe more to come about internals because it could hard to figure without knowing what's going on), but here is a little usage teaser:

Now instead of writing this:
return switch (e) {
   default: throw "error";
   case E1(f, x):
      switch (f) {
         default: throw "error";
         case F1:
            if (x < 5) x;
            else throw "error";
      }
};

You can write this:

return GSwitch.guarded(switch (e) {
   case E1(F1, x) = x < 5:
      x;
   default:
      throw "error";
});

Have fun :)
Robin

--
haXe - an open source web programming language
http://haxe.org



--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: pattern-match on enums with macros and hxpattern

Nicolas Cannasse
In reply to this post by John A. De Goes
Le 17/09/2010 22:56, John A. De Goes a écrit :
>
> Nested pattern matching and guarding are things that should be
> implemented in the compiler. You shouldn't have to create workaround for
> crippled language features.

Macros have been made to permit these kind of advances and experiments.
You're welcome to provide a compiler patch for efficient crossplatform
nested pattern matching if you dislike so called "crippled features".

Nicolas

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: pattern-match on enums with macros and hxpattern

John A. De Goes

You invented macros so we can fix switch statement? :-)

You will accept a compiler patch for cross-platform nested pattern matching with guarding?

Regards,

John A. De Goes
Twitter: @jdegoes
LinkedIn: http://linkedin.com/in/jdegoes

On Sep 17, 2010, at 3:20 PM, Nicolas Cannasse wrote:

> Le 17/09/2010 22:56, John A. De Goes a écrit :
>>
>> Nested pattern matching and guarding are things that should be
>> implemented in the compiler. You shouldn't have to create workaround for
>> crippled language features.
>
> Macros have been made to permit these kind of advances and experiments. You're welcome to provide a compiler patch for efficient crossplatform nested pattern matching if you dislike so called "crippled features".
>
> Nicolas
>
> --
> haXe - an open source web programming language
> http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: pattern-match on enums with macros and hxpattern

interaction-designer
In reply to this post by Robin Palotai
Hi John, Nicholas, Robin

Despite that John is probably right, but it's despite the criticism of course it's fine if people experiment(even only for the sake of experimenting). And I too believe I can understand Nicholas doesn't want to recreate scala, however that will not mean some very good features of other languages could be seriously implemented in design. Personally I think a lot of OOP minded people discard pattern matching because how it's implemented in most languages. However Scala's implementation is very elegant, despite of some criticism I have on the readability on some specific points (like case x :: xs =>, though very useful).

But If I see someone invited to make a patch for the compiler, I expect it to be a serious invitation. So are you serious about your invitation to John, Nicolas?

Simon


>Nested pattern matching and guarding are things that should be implemented in the compiler. You shouldn't have to create workaround for crippled language features.
>
>Also the syntax is not very intuitive. It should be:
>
>    case Foo(Bar(string), 230) if (string.length > 0): /* scala syntax - blah, blah blah */
>
>
>Or maybe:
>
>    case Foo(Bar(string), 230) | (string.length > 0): /* haskell syntax - blah, blah blah */
>
>
>Regards,

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: pattern-match on enums with macros and hxpattern

Nicolas Cannasse
Le 18/09/2010 10:13, [hidden email] a écrit :
> Hi John, Nicholas, Robin
>
> Despite that John is probably right, but it's despite the criticism of course it's fine if people experiment(even only for the sake of experimenting). And I too believe I can understand Nicholas doesn't want to recreate scala, however that will not mean some very good features of other languages could be seriously implemented in design. Personally I think a lot of OOP minded people discard pattern matching because how it's implemented in most languages. However Scala's implementation is very elegant, despite of some criticism I have on the readability on some specific points (like case x :: xs =>, though very useful).
>
> But If I see someone invited to make a patch for the compiler, I expect it to be a serious invitation. So are you serious about your invitation to John, Nicolas?

So far I'm ok to add enum nesting to haXe. I'm still not sure if/how I
want to introduce guarding, pattern matching on other structures
(anonymous types, lists, arrays) and the ! operator as defined by Robin
macro, so let's leave it aside right now.

Concerning a patch, it has to reach some level of quality in terms of
simplicity, performances (both compiletime and runtime) and backward
compatibility (the runtime code must perform/behave the same when not
using nested matching). If all is green I don't see any reason not to
accept such a patch.

@Simon : could you setup your mailer to correctly reply to the thread ?
Thunderbird will show a new thread for each of your answers which is not
very pleasant when following a topic.

Best,
Nicolas

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: pattern-match on enums with macros and hxpattern

Robin Palotai
  Now I hit a barrier when trying to use cases from multiple enum types
in the guarded switch (switching on Dynamic). It seems that the parser
enforces the "only constructors of the same type of enum" rule, so the
macro can't get the structure, where it could transform it to something
acceptable. What do you think, is there any measure possible to take?

Thanks,
Robin

2010.09.18. 11:45 keltezéssel, Nicolas Cannasse írta:

> Le 18/09/2010 10:13, [hidden email] a écrit :
>> Hi John, Nicholas, Robin
>>
>> Despite that John is probably right, but it's despite the criticism
>> of course it's fine if people experiment(even only for the sake of
>> experimenting). And I too believe I can understand Nicholas doesn't
>> want to recreate scala, however that will not mean some very good
>> features of other languages could be seriously implemented in design.
>> Personally I think a lot of OOP minded people discard pattern
>> matching because how it's implemented in most languages. However
>> Scala's implementation is very elegant, despite of some criticism I
>> have on the readability on some specific points (like case x :: xs
>> =>, though very useful).
>>
>> But If I see someone invited to make a patch for the compiler, I
>> expect it to be a serious invitation. So are you serious about your
>> invitation to John, Nicolas?
>
> So far I'm ok to add enum nesting to haXe. I'm still not sure if/how I
> want to introduce guarding, pattern matching on other structures
> (anonymous types, lists, arrays) and the ! operator as defined by
> Robin macro, so let's leave it aside right now.
>
> Concerning a patch, it has to reach some level of quality in terms of
> simplicity, performances (both compiletime and runtime) and backward
> compatibility (the runtime code must perform/behave the same when not
> using nested matching). If all is green I don't see any reason not to
> accept such a patch.
>
> @Simon : could you setup your mailer to correctly reply to the thread
> ? Thunderbird will show a new thread for each of your answers which is
> not very pleasant when following a topic.
>
> Best,
> Nicolas
>


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: pattern-match on enums with macros and hxpattern

Robin Palotai

Rethinking it, by passing multiple arguments as cases (instead of passing the whole switch) it may be possible.

Robin

On 2010.09.18. 23:27, "Robin Palotai" <[hidden email]> wrote:

 Now I hit a barrier when trying to use cases from multiple enum types in the guarded switch (switching on Dynamic). It seems that the parser enforces the "only constructors of the same type of enum" rule, so the macro can't get the structure, where it could transform it to something acceptable. What do you think, is there any measure possible to take?

Thanks,
Robin

2010.09.18. 11:45 keltezéssel, Nicolas Cannasse írta:


>
> Le 18/09/2010 10:13, [hidden email] a écrit :
>>
>> Hi John, Nicholas, Robin
>>...


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: pattern-match on enums with macros and hxpattern

Nicolas Cannasse
In reply to this post by Robin Palotai
Le 18/09/2010 23:27, Robin Palotai a écrit :
> Now I hit a barrier when trying to use cases from multiple enum types in
> the guarded switch (switching on Dynamic). It seems that the parser
> enforces the "only constructors of the same type of enum" rule, so the
> macro can't get the structure, where it could transform it to something
> acceptable. What do you think, is there any measure possible to take?

The parser is not capable of enforcing any typing rule. Could you show
some code that doesn't fit in your macro ?

Best,
Nicolas

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

some flash code optimisations

Renaud Bardet-2
Hi list,

Currently I'm trying to reach best performances on a flash game and there
are some way of coding I'd like to share.

First of all I think everybody will agree that in flash the less there are
instanciation and function calls the better we are

I was already using pools to store a lot of 'empty' objects in order to
reuse them without new instanciations
(if you don't know the concept, read this well explained arcticle from my
friends at alkemi-games :
http://blog.alkemi-games.com/index.php?post/2010/05/23/Alkemi-Flash-Bitmap-Renderer,-part-2-:-pools )

for the second concern I tried some around the inline functionality,
as you know one of the inconvenients of inlining is the incompatibility with
overriding, so it's difficult to play with both inheritence and inlining,
using List and Hash in intensively called functions such as a render loop
was one of the biggest performance leak in my app first version because as
part of the standard library none of their functions are inlined, so I
managed to write my own lists, pools and hash using haxe.rtti.Generic and
inline.
Also most of my render lib and game specific class use (abuse of) inlining,
but as a strongly ObjectOriented mind (I come from Java) I couldn't fully
abandon Object conception,
following is a method I'm currently experimenting and I'd really like your
opinion about it.

The goal is to avoid classic inheritance and implementation which in flash
are related to runtime opertaions (each super() is a function call), but
still use inherited types.
Typedefs allow type inheritance and do not mean any function call since it's
only typechecking.
For two class A and B as B extends A and we would code like :

class A {
var alpha ;
var beta ;
function foo () {...}
}

class B extends A {
var gamma ;
override function foo () {...}
}

create a typedef for A (I write it in an empty class in each package, that I
call _packageName_Types) :

typedef T_A = {
var alpha : Int ;
var beta : Int ;
function foo () : Void ;
}

now every variable typed T_A will accept a A or a B because they have the
right fields, so get rid of inheritence by rewritting B as :

class B {
var alpha ;
var beta ;
var gamma ;
function foo () {...}
}

and now that B.foo is not overriding, you can inline it !

if you have a third class C extends B, write the T_B typedef like
typedef T_B = { >T_A,
var omega : Float ;
}

drawbacks are :
You need to be very carefull while attempting modifications, because there's
a lot of code copying, so be sure to repercute changes, it's not quite easy
on big teams
Typedefs are not allowed as a pseudoType when using haxe.rtti.Generic, so
either use classic genericity (less efficient in flash) or write the
specialised list/pool/hash for this type
I didn't eprouve this concept so I currently don't know much of it's
limitations

Thanks for your point of view about this technique and flash optimisation in
general.
Bests,

Renaud

--
Renaud Bardet
Independant Game Developer, Nantes, France


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: some flash code optimisations

Nicolas Cannasse
Le 20/09/2010 11:58, Renaud Bardet a écrit :
> Hi list,
[...]

> You need to be very carefull while attempting modifications, because
> there's a lot of code copying, so be sure to repercute changes, it's not
> quite easy on big teams
> Typedefs are not allowed as a pseudoType when using haxe.rtti.Generic,
> so either use classic genericity (less efficient in flash) or write the
> specialised list/pool/hash for this type
> I didn't eprouve this concept so I currently don't know much of it's
> limitations
>
> Thanks for your point of view about this technique and flash
> optimisation in general.

The main drawback you'll have here is that when accessing your class
instance through a typedef type, all fields access will be performed
dynamically since all typedef compiles to AS3 * type.

One another path might simply be to use "using" which enable extending
an existing class without doing actual overriding/inheritance.

Best,
Nicolas

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: pattern-match on enums with macros and hxpattern

Robin Palotai
In reply to this post by Nicolas Cannasse
  Hm, this seems true, then I think my generated expression caused the
error then. Sorry for the mis-reporting then.
Initially this made me switch away from taking a "switch" structure as
an input of the macro, but I think the syntax change is a positive
outcome afterall.

Thanks,
Robin

> The parser is not capable of enforcing any typing rule. Could you show
> some code that doesn't fit in your macro ?
>
> Best,
> Nicolas
>


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: some flash code optimisations

Renaud Bardet-2
In reply to this post by Nicolas Cannasse
Ouch, I didn't know typedef worked that way,
it's definitely a bad idea

thanks nicolas

--------------------------------------------------
From: "Nicolas Cannasse" <[hidden email]>
Sent: Monday, September 20, 2010 12:33 PM
To: "The haXe compiler list" <[hidden email]>
Subject: Re: [haXe] some flash code optimisations

> Le 20/09/2010 11:58, Renaud Bardet a écrit :
>> Hi list,
> [...]
>> You need to be very carefull while attempting modifications, because
>> there's a lot of code copying, so be sure to repercute changes, it's not
>> quite easy on big teams
>> Typedefs are not allowed as a pseudoType when using haxe.rtti.Generic,
>> so either use classic genericity (less efficient in flash) or write the
>> specialised list/pool/hash for this type
>> I didn't eprouve this concept so I currently don't know much of it's
>> limitations
>>
>> Thanks for your point of view about this technique and flash
>> optimisation in general.
>
> The main drawback you'll have here is that when accessing your class
> instance through a typedef type, all fields access will be performed
> dynamically since all typedef compiles to AS3 * type.
>
> One another path might simply be to use "using" which enable extending an
> existing class without doing actual overriding/inheritance.
>
> Best,
> Nicolas
>
> --
> haXe - an open source web programming language
> http://haxe.org
>

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: pattern-match on enums with macros and hxpattern

Robin Palotai
In reply to this post by Robin Palotai
I updated the hxpattern project, now it has pattern matching on mixed enum types, and also has a new, more compact syntax. Also incorporated John's suggestion for | delimiting the guard. The default case is now marked with ~<default expr>.

return Hxpat.gswitch( e,
   E1(F1, x) | (x < 5) = x;
   ~throw "error";
);

BR,
Robin

2010.09.20. 14:03 keltezéssel, Robin Palotai írta:
 Hm, this seems true, then I think my generated expression caused the error then. Sorry for the mis-reporting then.
Initially this made me switch away from taking a "switch" structure as an input of the macro, but I think the syntax change is a positive outcome afterall.

Thanks,
Robin

The parser is not capable of enforcing any typing rule. Could you show some code that doesn't fit in your macro ?

Best,
Nicolas




--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: pattern-match on enums with macros and hxpattern

John A. De Goes

This is much nicer. Although I would suggest underscore for default case:

_ = throw "error";

If it's possible to use a macro with "using", then it can be written:

return e.gswitch({
  E1(F1, x) | (x < 5) = x;

  _ = throw "error";
});

Regards,

John A. De Goes
Twitter: @jdegoes 
LinkedIn: http://linkedin.com/in/jdegoes

On Sep 20, 2010, at 9:10 AM, Robin Palotai wrote:

I updated the hxpattern project, now it has pattern matching on mixed enum types, and also has a new, more compact syntax. Also incorporated John's suggestion for | delimiting the guard. The default case is now marked with ~<default expr>.

return Hxpat.gswitch( e,
   E1(F1, x) | (x < 5) = x;
   ~throw "error";
);

BR,
Robin

2010.09.20. 14:03 keltezéssel, Robin Palotai írta:
 Hm, this seems true, then I think my generated expression caused the error then. Sorry for the mis-reporting then.
Initially this made me switch away from taking a "switch" structure as an input of the macro, but I think the syntax change is a positive outcome afterall.

Thanks,
Robin

The parser is not capable of enforcing any typing rule. Could you show some code that doesn't fit in your macro ?

Best,
Nicolas



--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: pattern-match on enums with macros and hxpattern

Robin Palotai
The underscore is a good idea, thanks, committed.
Using doesn't seem to be possible using macro now, but would be fun in the future.

Robin

2010.09.20. 17:28 keltezéssel, John A. De Goes írta:

This is much nicer. Although I would suggest underscore for default case:

_ = throw "error";

If it's possible to use a macro with "using", then it can be written:

return e.gswitch({
  E1(F1, x) | (x < 5) = x;

  _ = throw "error";
});

Regards,

John A. De Goes
Twitter: @jdegoes 
LinkedIn: http://linkedin.com/in/jdegoes

On Sep 20, 2010, at 9:10 AM, Robin Palotai wrote:

I updated the hxpattern project, now it has pattern matching on mixed enum types, and also has a new, more compact syntax. Also incorporated John's suggestion for | delimiting the guard. The default case is now marked with ~<default expr>.

return Hxpat.gswitch( e,
   E1(F1, x) | (x < 5) = x;
   ~throw "error";
);

BR,
Robin

2010.09.20. 14:03 keltezéssel, Robin Palotai írta:
 Hm, this seems true, then I think my generated expression caused the error then. Sorry for the mis-reporting then.
Initially this made me switch away from taking a "switch" structure as an input of the macro, but I think the syntax change is a positive outcome afterall.

Thanks,
Robin

The parser is not capable of enforcing any typing rule. Could you show some code that doesn't fit in your macro ?

Best,
Nicolas



--
haXe - an open source web programming language
http://haxe.org



--
haXe - an open source web programming language
http://haxe.org