December 30, 2007
On 12/30/07, Bastiaan Veelo <Bastiaan@veelo.net> wrote:
> If not, that would be confusing to me, as you will
> be able to switch on some enums but not on others.

You can't switch on an anonymous enum. Anonymous enums have no type, and therefore it is not even /possible/ to generate an expression whose type is that of an anonymous enum!

So switch/case survives unharmed.
December 30, 2007
On Sun, 30 Dec 2007 11:27:17 +0000, Janice Caron wrote:

> On 12/30/07, Bastiaan Veelo <Bastiaan@veelo.net> wrote:
>> If not, that would be confusing to me, as you will
>> be able to switch on some enums but not on others.
> 
> You can't switch on an anonymous enum. Anonymous enums have no type, and therefore it is not even /possible/ to generate an expression whose type is that of an anonymous enum!
> 
> So switch/case survives unharmed.

And yet this compiles and runs ...

// -------------
import std.stdio;

enum
{
one = 1,
two = 2,
three = 3
}

void main()
{
    auto x = three;

    switch (x)
    {
        case one: writefln("ONE"); break;
        case two: writefln("TWO"); break;
        case three: writefln("THREE"); break;
    }
}
// -------------

-- 
Derek Parnell
Melbourne, Australia
skype: derek.j.parnell
December 30, 2007
Walter Bright wrote:
> Anonymous enums don't have a type (and didn't in D1.0, either). There's no way to get a grip on such a type anyway, as it has no name and:
>     enum { FOO, BAR } x;
> style declarations are not allowed in D.

Now I'm confused. I thought an anonymous enum was an enum without a name. But it is entirely possible to create an anonymous enum with a type, for example:

	enum : uint {red, green, blue}

At least I use that kind of enums a lot and I allways thought of these as anonymous enums.

I call enums without a type "typeless enums".

LLAP,
Sascha Katzner
December 30, 2007
Derek Parnell wrote:
> On Sun, 30 Dec 2007 11:27:17 +0000, Janice Caron wrote:
> 
>> On 12/30/07, Bastiaan Veelo <Bastiaan@veelo.net> wrote:
>>> If not, that would be confusing to me, as you will
>>> be able to switch on some enums but not on others.
>> You can't switch on an anonymous enum. Anonymous enums have no type,
>> and therefore it is not even /possible/ to generate an expression
>> whose type is that of an anonymous enum!
>>
>> So switch/case survives unharmed.
> 
> And yet this compiles and runs ...
> 
> [source: switch with anon enum]

And I'd have been surprised if not... if it was called
"manifest", would anyone at all get the idea that you
can't case against them, because they are something oh
so entirely different from a literal number?

Ooops, wait... wasn't it supposed to be just like one? =)

regards, frank

---

Making a statement bold and confident doesn't make it true.
December 30, 2007
Jérôme M. Berger wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Walter Bright wrote:
>> What do we do with:
>>
>>     const MyInt m = 3;
>>     auto n = m;
>>
>> Does n get const or not? If it is, now it is behaving differently from
>> other types, and so is not a plug-in replacement. If it does not, what
>> happens if MyInt has a pointer member? Suddenly, the const gets stripped
>> from the pointer, and there is no const-correctness.
> 
> 	OK, I see your point, but like Bill said I think the issue here is
> with the "auto" type inference rather than the "const". What is
> needed is for "auto" to be smarter than it is now, namely:
> 
>  - for atomic types, strip the const;
>  - for pointers, if the language supports head const, then strip the
> tailmost const (ie make a mutable pointer to const data) otherwise
> keep the const;
>  - for classes, keep the const;
>  - for struct, the compiler already keeps track of whether the
> struct contains pointers or not because of the GC, doesn't it? In
> that case, if the struct contains pointers keep the const, and if it
> doesn't strip it (1);
>  - in all cases, allow a "const auto" statement to force an "auto"
> declaration to be "const". This would work even if the right hand
> expression is not "const":
> 	int x = 42;
> 	const auto y = x;       // y is now "const int"
> 
> 		Jerome
> 
> (1) It would be even nicer if the compiler could keep track of
> whether there are *mutable* pointers in the struct and strip the
> "const" from the "auto" variable if all pointers in the struct are
> "const" anyway, so it wouldn't break const-correctness:
> 
> struct {
>    int value;
>    const int* pointer;
> } ConstStruct;
> 
> struct {
>    int value;
>    int* pointer;
> } MutableStruct;
> 
> const ConstStruct   cs0;
> const MutableStruct ms0;
> auto cs1 = cs0;         // <= cs1 is a ConstStruct since all
>                         // pointers inside are const anyway.
> auto ms1 = ms0;         // <= ms1 is a const MutableStruct.

That doesn't really make sense. You could push off const one level:
ms1.value = 3;          // Fine
*ms1.pointer = 3;       // Error; pointer is const

That would make sense, but it would be hard to do, and it would be hard for a programmer to think "okay, I just did this assignment, now what is const in the struct and what isn't?"

Structs make const hard. It'd be easier with just classes, I think.
December 30, 2007
Derek Parnell wrote:
> On Sun, 30 Dec 2007 11:27:17 +0000, Janice Caron wrote:
> 
>> On 12/30/07, Bastiaan Veelo <Bastiaan@veelo.net> wrote:
>>> If not, that would be confusing to me, as you will
>>> be able to switch on some enums but not on others.
>>
>> You can't switch on an anonymous enum. Anonymous enums have no type,
>> and therefore it is not even /possible/ to generate an expression
>> whose type is that of an anonymous enum!
>>
>> So switch/case survives unharmed.
> 
> And yet this compiles and runs ...
> 
> // -------------
> import std.stdio;
> 
> enum
> {
> one = 1,
> two = 2,
> three = 3
> }
> 
> void main()
> {
>     auto x = three;
>        switch (x)
>     {
>         case one: writefln("ONE"); break;
>         case two: writefln("TWO"); break;
>         case three: writefln("THREE"); break;
>     }
> }     // -------------
> 

Yes, and although the extended enum would allow three to be defined as 3f, then case three would not compile according to the current spec. That is obvious in this example, but it is a confusing inconsistency in the relation between enum and switch. enum and switch have always been compatible in my mind, but that is about to change...

Bastaan.
December 30, 2007
On 12/30/07, Janice Caron <caron800@googlemail.com> wrote:
> You can't switch on an anonymous enum. Anonymous enums have no type, and therefore it is not even /possible/ to generate an expression whose type is that of an anonymous enum!
>
> So switch/case survives unharmed.

OK, so everyone pointed out I got that wrong. Thanks, guys.

What I meant was: you can't switch on a heterogenous anonymous enum, because heterogenous anonymous enums have no type.

Sorry for the confusion.
December 30, 2007
Janice Caron wrote:
> What I meant was: you can't switch on a heterogenous anonymous enum,
> because heterogenous anonymous enums have no type.

with

  enum
  {
    int    one   = 1;
    float  two   = 2.0;
    string three = "three";
  }

I'd expect

  void foo(int x)
  {
    switch (x)
    {
      case one: writefln("ONE"); break;     // this should be legal
      case two: writefln("TWO"); break;     // but not this
      case three: writefln("THREE"); break; // much less this
    }
  }


because to me the rule "case guards can only be of integral type"
seems to make the most sense. I'd be rather disappointed if case
one didn't work...

regards, frank


December 30, 2007
0ffh wrote:
>   enum
>   {
>     int    one   = 1;
>     float  two   = 2.0;
>     string three = "three";
>   }

Ooops, I suppose there should be commas here not semicolons...

regards, frank
December 30, 2007
0ffh wrote:
> because to me the rule "case guards can only be of integral type"
> seems to make the most sense. I'd be rather disappointed if case
> one didn't work...

Actually, D also allows string switch. However, I'm pretty sure you can't mix int "switch" with string "case"s :P.

Spec reference: http://www.digitalmars.com/d/1.0/statement.html#SwitchStatement
---
/Expression/ is evaluated. The result type T must be of integral type or char[], wchar[] or dchar[]. The result is compared against each of the case expressions. If there is a match, the corresponding case statement is transferred to.
---