switch statement clarification

71 views
Skip to first unread message

John Evans

unread,
May 31, 2012, 3:31:31 PM5/31/12
to mi...@dartlang.org
So in the new spec for switch, we won't be able to do this?

class MyEnum{

  final int _val;
  
  const MyEnum(this._val);
  
  static final First = const MyEnum(1);
  static final Second = const MyEnum(2);
  static final Third = const MyEnum(3); 
}

main(){
  
  var test = MyEnum.Second;
  
  switch(test){
    case MyEnum.First:
      print('first');
      break;
    case MyEnum.Second:
      print('second');
      break;
    case MyEnum.Third:
      print('third');
      break;
    default:
      break;
  }
}


Eli Brandt

unread,
May 31, 2012, 3:56:05 PM5/31/12
to John Evans, mi...@dartlang.org
On Thu, May 31, 2012 at 12:31 PM, John Evans <pru...@gmail.com> wrote:
So in the new spec for switch, we won't be able to do this?


That's my understanding.  We can work around by exposing a getter for the "val" in the enum pattern, and switching on that.

Eli

John Evans

unread,
May 31, 2012, 4:18:48 PM5/31/12
to mi...@dartlang.org, John Evans
Bummer.  It's so much cleaner this way.  But yes, easy enough to expose the underlying type.  People will also have to be careful to only use int and String as the underlying type.

On Thursday, May 31, 2012 2:56:05 PM UTC-5, Eli Brandt wrote:

Bob Nystrom

unread,
May 31, 2012, 4:41:59 PM5/31/12
to John Evans, mi...@dartlang.org
On Thu, May 31, 2012 at 1:18 PM, John Evans <pru...@gmail.com> wrote:
Bummer.  It's so much cleaner this way.  But yes, easy enough to expose the underlying type.  People will also have to be careful to only use int and String as the underlying type.

Right. This change is a drag if you were using the type-safe enum pattern and switching on it. If you still want to define your "enums" like that, you can always just do chained ifs instead:

if (test == MyEnum.First) {
  print('first');
} else if (test == MyEnum.Second) {
  print('second');
} else if (test == MyEnum.Third) {
  print('third');
}

- bob

Eli Brandt

unread,
May 31, 2012, 4:54:00 PM5/31/12
to John Evans, mi...@dartlang.org
On Thu, May 31, 2012 at 12:56 PM, Eli Brandt <e...@google.com> wrote:
On Thu, May 31, 2012 at 12:31 PM, John Evans <pru...@gmail.com> wrote:
So in the new spec for switch, we won't be able to do this?


That's my understanding.  We can work around by exposing a getter for the "val" in the enum pattern, and switching on that.


Actually, sorry, I think it won't work to put a MyEnum.First.val in the switch case.  Spec:
"It is a compile-time error if the expressions ek are not compile-time constants [my emphasis], of type int or String"
 
Eli

Don Olmstead

unread,
May 31, 2012, 6:35:04 PM5/31/12
to Eli Brandt, John Evans, mi...@dartlang.org
I know this has been brought up before but I'm still not seeing why an enum declaration wouldn't be good for the language. C# enums are nice, especially with the flag attribute. For something like WebGL it would be really nice to have that facility. Without it people end up reinventing the wheel quite a bit, which if my memory serves occurred in Java before they added enums.

Kevin Moore

unread,
May 31, 2012, 6:36:49 PM5/31/12
to Don Olmstead, Eli Brandt, John Evans, mi...@dartlang.org
Star and encourage the existing issue: http://dartbug.com/88

Bob Nystrom

unread,
May 31, 2012, 6:44:10 PM5/31/12
to Don Olmstead, Eli Brandt, John Evans, mi...@dartlang.org
On Thu, May 31, 2012 at 3:35 PM, Don Olmstead <don.j.o...@gmail.com> wrote:
I know this has been brought up before but I'm still not seeing why an enum declaration wouldn't be good for the language.

I think we generally agree it would be good for the language, it's just a question of time. We have a lot on our plate and we're trying to keep things as simple as we can at least for now. We're trying not to let the spec get too far ahead of the implementations. It's (relatively) easy to add a new feature to the spec, but that adds a lot of work for a bunch of people on the team who are already plenty busy as it is.

I wouldn't be surprised if enums made it in, possibly even before 1.0, but it still might be a while before they show up. (And don't consider this a promise, either. It's not up to me. :) )

Cheers,

- bob

Don Olmstead

unread,
May 31, 2012, 6:53:12 PM5/31/12
to Bob Nystrom, Eli Brandt, John Evans, mi...@dartlang.org
Assuming they are implemented is there a particular language whose implementation Dart's would be based on? I always viewed an enumeration as a way of grouping some constant values so they're type safe and have verbose names. The Java way is a bit overblown, so I personally wouldn't like that kind of implementation, which is why I'm having a hard time starring Issue 88.

Peter Ahé

unread,
Jun 1, 2012, 2:37:13 AM6/1/12
to Don Olmstead, Bob Nystrom, Eli Brandt, John Evans, mi...@dartlang.org
Hi Don,

I think it would make sense for you  to file a bug and explain your view. 

Here is what I would make sure to include:

• a good name for your proposal

• your proposal defined in terms of itself

• why it shouldn't be closed as a dupe of 88

• why it is different or similar from other languages, and why these differences or similarities are important

Cheers,
Peter

Lasse R.H. Nielsen

unread,
Jun 1, 2012, 6:16:45 AM6/1/12
to Eli Brandt, John Evans, mi...@dartlang.org
Yes, you have to declare val as const as well. I believe that's
allowed by the specification.
Then you can write:
switch (test.val) {
case MyEnum.First.val: ...
case MyEnum.Second.val: ...
case MyEnum.Third.val: ...
}

If/when enums make it into the language, it's still unlikely to be
using the type-safe enum pattern, so if you want type-safe enums, you
need to do something like this anyway.

Alternatively, you can add your own dispatch on the enum object:
test.select(() => print("first"),
() => print("second"),
() => print("third"))

And I think I'll write a request for allowing any compile-time
constant in a switch,
/L
--
Lasse R.H. Nielsen
l...@google.com
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K -
Denmark - CVR nr. 28 86 69 84

Kasper Lund

unread,
Jun 1, 2012, 6:25:27 AM6/1/12
to Lasse R.H. Nielsen, Eli Brandt, John Evans, mi...@dartlang.org
On Fri, Jun 1, 2012 at 12:16 PM, Lasse R.H. Nielsen <l...@chromium.org> wrote:
> And I think I'll write a request for allowing any compile-time
> constant in a switch,

We'll definitely take a look at allowing this.

Cheers,
Kasper

Don Olmstead

unread,
Jun 3, 2012, 1:13:53 PM6/3/12
to Peter Ahé, Bob Nystrom, Eli Brandt, John Evans, mi...@dartlang.org
Here's the associated issue  http://code.google.com/p/dart/issues/detail?id=3371 

Florian Loitsch

unread,
Jun 8, 2012, 6:25:04 PM6/8/12
to Lasse R.H. Nielsen, Eli Brandt, John Evans, mi...@dartlang.org
On Fri, Jun 1, 2012 at 12:16 PM, Lasse R.H. Nielsen <l...@chromium.org> wrote:
On Thu, May 31, 2012 at 10:54 PM, Eli Brandt <e...@google.com> wrote:
>
>
> On Thu, May 31, 2012 at 12:56 PM, Eli Brandt <e...@google.com> wrote:
>>
>> On Thu, May 31, 2012 at 12:31 PM, John Evans <pru...@gmail.com> wrote:
>>>
>>> So in the new spec for switch, we won't be able to do this?
>>>
>>
>> That's my understanding.  We can work around by exposing a getter for the
>> "val" in the enum pattern, and switching on that.
>>
>
> Actually, sorry, I think it won't work to put a MyEnum.First.val in the
> switch case.  Spec:
> "It is a compile-time error if the expressions ek are not compile-time
> constants [my emphasis], of type int or String"

Yes, you have to declare val as const as well. I believe that's
allowed by the specification.
Then you can write:
 switch (test.val) {
   case MyEnum.First.val: ...
A little late to the party, but if I'm not wrong reading a field from a compile-time constant is not a compile-time expression.


   case MyEnum.Second.val: ...
   case MyEnum.Third.val: ...
 }

If/when enums make it into the language, it's still unlikely to be
using the type-safe enum pattern, so if you want type-safe enums, you
need to do something like this anyway.

Alternatively, you can add your own dispatch on the enum object:
 test.select(() => print("first"),
                 () => print("second"),
                 () => print("third"))

And I think I'll write a request for allowing any compile-time
constant in a switch,
/L
--
Lasse R.H. Nielsen
l...@google.com
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K -
Denmark - CVR nr. 28 86 69 84



--
Give a man a fire and he's warm for the whole day,
but set fire to him and he's warm for the rest of his life. - Terry Pratchett

Lasse R.H. Nielsen

unread,
Jun 9, 2012, 7:54:02 AM6/9/12
to Florian Loitsch, Eli Brandt, John Evans, mi...@dartlang.org
On Sat, Jun 9, 2012 at 12:25 AM, Florian Loitsch <floi...@google.com> wrote:
> On Fri, Jun 1, 2012 at 12:16 PM, Lasse R.H. Nielsen <l...@chromium.org>
> wrote:

>> Yes, you have to declare val as const as well. I believe that's
>> allowed by the specification.
>> Then you can write:
>>  switch (test.val) {
>>    case MyEnum.First.val: ...
>
> A little late to the party, but if I'm not wrong reading a field from a
> compile-time constant is not a compile-time expression.

As I read it, if the field is declared const, it should be a constant
variable (http://www.dartlang.org/docs/spec/latest/dart-language-specification.html#kix.6b1cgvgf1cyq)
and a reference to a constant variable is a compile-time constant
expression (http://www.dartlang.org/docs/spec/latest/dart-language-specification.html#h.9asvt38phduq).

The big questions is what "reference to a constant variable" covers.
Is it only local variables, only static variables, or can it also be
instance variables of compile time constant objects?

I can see a good use of the last case (e.g., here), so I obviously
want it to cover that.
On the other hand, it's not at all obvious what:

class A {
const int x = 42;
foo() => const B(x);
}

will do if you subclass A and overwrite x.
You also need different subclasses of the typesafe enum to have
different const variable values, since you can't write:
class E {
const int id;
const E(this.id);
}
(and that's probably a good thing too).

My guess is that const instance variables will be disallowed
eventually, but the current spec allows them, and may or may not allow
references to them through compile time constant instances.

Ofcourse const declarations are not implemented anywhere yet. :)
Reply all
Reply to author
Forward
0 new messages