This switch statement worked in 2.10... why not in Haxe 3?

267 views
Skip to first unread message

Rezmason

unread,
May 10, 2013, 10:57:19 AM5/10/13
to haxe...@googlegroups.com
I'm aware that switch statements in Haxe 3 have picked up some cool new features. However, switch statements in Haxe 2.10 code that don't use Enums should probably work in Haxe 3, no?

But when I try to compile my project's old prototype in Haxe 3, this switch statement's cases throw the compile error "This pattern is unused". I'm not sure why– it's a short, conventional statement, written to avoid a string of if-else-ifs, and it's clearly possible for the value of the control expression to equal the values of the errant cases. What's going on?

clemos

unread,
May 10, 2013, 11:11:05 AM5/10/13
to haxe...@googlegroups.com
Hi,

This is the expected behaviour. 
It's due to the fact that case expressions need to be constant, now:
If not constants, the identifiers are considered capture variables, so in your case the 4 cases indeed match the same pattern (=capture everything), hence this "this pattern is unused" message.
I believe there is an opened issue in google code to improve the error messages in these situations.

You need to rewrite it either with "else/ifs" or using "guards" like this :
case a if( a == rotateLeftButton ) :

I don't really like this constraint either, as you can see here:
So I wrote a small macro that allows both pattern matching and old style case statements with existing variable identifiers:
It has not been heavily tested, but should work as expected in most cases.

Regards,
Clément


On Fri, May 10, 2013 at 4:57 PM, Rezmason <jeremy...@gmail.com> wrote:
I'm aware that switch statements in Haxe 3 have picked up some cool new features. However, switch statements in Haxe 2.10 code that don't use Enums should probably work in Haxe 3, no?

But when I try to compile my project's old prototype in Haxe 3, this switch statement's cases throw the compile error "This pattern is unused". I'm not sure why– it's a short, conventional statement, written to avoid a string of if-else-ifs, and it's clearly possible for the value of the control expression to equal the values of the errant cases. What's going on?

--
To post to this group haxe...@googlegroups.com
http://groups.google.com/group/haxelang?hl=en
---
You received this message because you are subscribed to the Google Groups "Haxe" group.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Simon Krajewski

unread,
May 10, 2013, 11:26:26 AM5/10/13
to haxe...@googlegroups.com
Am 10.05.2013 17:11, schrieb clemos:
>
> So I wrote a small macro that allows both pattern matching and old
> style case statements with existing variable identifiers:
> https://gist.github.com/clemos/5443026
> It has not been heavily tested, but should work as expected in most cases.

Try compiling this:

var x = macro 1;
MyMacro.HybridSwitch.build(switch(x.expr) {
case EParenthesis(x): x;
case _: null;
});

EParenthesis(x) is a valid ECall in the context, so your macro replaces
it with
case __value__ if(__value__==EParenthesis(x))
which doesn't fly with the compiler.

In general I think that "pattern can be typed" is not a strong enough
criteria, because patterns and especially identifiers can be typed for
all sorts of reason. You may be in luck if you handle above enum case
and everything works out somehow, but that macro will still turn a "case
true" into "case __value__ if (__value__ == true)", which is a bit awkward.

Simon

Rezmason

unread,
May 10, 2013, 11:35:04 AM5/10/13
to haxe...@googlegroups.com
Since my code is a prototype for my full project, I'll just have it slog through a vanilla if-else-if statement. 

Ideally I'd use an object map instead of a switch-type deal, but I didn't really have good code design in mind when I hacked this thing together in 2010. :D

clemos

unread,
May 10, 2013, 12:23:25 PM5/10/13
to haxe...@googlegroups.com
As I said it's largely untested, so I should avoid presenting it as an alternative in the first place ;)

You're right, the way it determines if the expression needs to be changed is very weak, as it just checks that the expression can simply be typed in the context... 
That's just the trick I used to determine if the expression has unknown identifiers.

Constant expressions (true, myInlineConstant, ...) should also be detected and kept as is, which is not the case right now.
The thing is I don't know how to tell if the expression is constant.

As for your very example, it's even more complex: it should probably be replaced with something like "case EParenthesis( a ) if ( x == a ) :".
I guess I'd need to walk down the whole expression tree to convert it to a pattern + guard if/when parameters expressions use known identifiers... 
which brings us back to proper detection of known identifiers...

The macro was rather a quick and dirty PoC than a full featured alternative, you're right.

Regards,
Clément

Jason O'Neil

unread,
May 10, 2013, 8:13:01 PM5/10/13
to haxe...@googlegroups.com
Hi

In the thread Clément linked to, I also had a go at writing a macro to emulate the classic style, but mine was naive and merely transformed it into an if/else tree, so it wouldn't work on enums/capturing, but it will work for comparing to a static variable as you're wanting:

https://gist.github.com/jasononeil/5429516

So it's pretty naive, and will throw a compile error if you try to do anything like capturing, but it would have the same effect as you writing if/elseif/else statements.

Jason


--
Reply all
Reply to author
Forward
0 new messages