June 30, 2010
Introducing a second kind of switch in D was bad because it's a special case, it duplicates a syntax already present, making the language more complex, etc. (one of the bigger faults of C++ is to have two ways to do everything, one inherited from C and one new). But given the constraints D is designed for (to keep the same semantics of C syntax or to disallow it), it can be acceptable even if inelegant.

I think the design of final switch needed more public discussions and more thinking.

One problem of the 'final switch' can be solved disallowing the automatic fall-through in both kinds of switch.

The current implementation of final switch seems to have some problems, I have done some tests below.

This is a normal usage of final switch, repeating the enum name into each case is not elegant, but it can be accepted:

void main() {
    //static enum E1 { A, B } // wrong
    enum ThisIsAnEnum { A, B }
    E1 e1;
    final switch(e1) {
        case ThisIsAnEnum.A: break;
        case ThisIsAnEnum.B: break;
    }
}


It seems final switch doesn't "work" in this easy situation, and ignores the missing case 7 (final switch is not supposed to do this, so this is not a bug, but it can become an enhancement request):

void main() {
    uint ui;
    final switch(ui % 8) {
        case 0: break;
        case 1: break;
        case 2: break;
        case 3: break;
        case 4: break;
        case 5: break;
        case 6: break;
    }
}



If I have 256 values in a ubyte I can omit them all:

void main() {
    ubyte u;
    final switch(u) {
    }
}



This shows that CaseRangeStatements are not allowed in a final switch, what's bad in a CaseRangeStatement? It's not bug-prone:

void main() {
    ubyte u;
    final switch(u) {
        case ubyte.min: .. case 0: break;
        case 1: .. case ubyte.max: break;
    }
}
// test.d(4): Error: case ranges not allowed in final switch


Strings are allowed and "ignored":

void main() {
    string s;
    final switch(s) {
    }
}


But string enums are not allowed, I don't know why (can this become another enhancement request):

void main() {
    enum E2 : string { C="foo", D="bar" }
    E2 e2;
    final switch(e2) { // error: Error: 'e2' is not of integral type, it is a E2
        case E2.C: break;
        case E2.D: break;
    }
}



I think a final switch like this is useless, because it currently can't contain CaseRangeStatements and default and it can't contain that many cases, so maybe it's better to disallow this:

void main() {
    int i;
    final switch(i) {
    }
}

Bye,
bearophile
Top | Discussion index | About this forum | D home