www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - No case ranges in final switches?

reply bearophile <bearophileHUGS lycos.com> writes:
Do you know why final switches disallow case ranges? Case ranges are not
bug-prone:


void main() {
    ubyte u;
    final switch (u) {
        case 0: .. case 100:
            break;
        case 101: .. case 255:
            break;
    }
}


DMD 2.052 gives the errors:
test.d(4): Error: case ranges not allowed in final switch
test.d(6): Error: case ranges not allowed in final switch

Thank you and bye,
bearophile
Mar 06 2011
parent reply Bekenn <leaveme alone.com> writes:
On 3/6/2011 1:11 PM, bearophile wrote:
 Do you know why final switches disallow case ranges? Case ranges are not
bug-prone:


 void main() {
      ubyte u;
      final switch (u) {
          case 0: .. case 100:
              break;
          case 101: .. case 255:
              break;
      }
 }

Final switch is really just meant to be used with enums; since enumeration values don't have to cover the whole range of possible base type values, and enumeration values don't often have a natural ordering, ranges make little sense there.
Mar 06 2011
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday 06 March 2011 18:26:26 Bekenn wrote:
 On 3/6/2011 1:11 PM, bearophile wrote:
 Do you know why final switches disallow case ranges? Case ranges are not
 bug-prone:
 
 
 void main() {
 
      ubyte u;
      final switch (u) {
      
          case 0: .. case 100:
              break;
          
          case 101: .. case 255:
              break;
      
      }
 
 }

Final switch is really just meant to be used with enums; since enumeration values don't have to cover the whole range of possible base type values, and enumeration values don't often have a natural ordering, ranges make little sense there.

Yeah. While I can see how you might want to use a final switch here, final switches were really intended for enums, and I'm not sure that they really work properly with anything else (I'm not even sure that they work properly with enums - IIRC last time I tried to use one, it didn't enforce anything; hopefully that's changed by now though). - Jonathan M Davis
Mar 06 2011
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Bekenn:

 Final switch is really just meant to be used with enums; since 
 enumeration values don't have to cover the whole range of possible base 
 type values, and enumeration values don't often have a natural ordering, 
 ranges make little sense there.

Thank you for your answer. If something doesn't have an ordering, then it's right to disallow the case range on it. But I'd like to be able to use case ranges in safer final switches on bytes/ubytes/chars. ------------------------- Jonathan M Davis:
Yeah. While I can see how you might want to use a final switch here, final
switches were really intended for enums,<

You often say that language features must pull their weight. Artificially restricting the usability of final switches to just enums makes them not pull their weight. There are times when I'd like to do this, but DMD is buggy here (I don't remember if I have already put this in Bugzilla): void main() { int x = 100; final switch (x % 3) { case 0: /*...*/ break; case 1: /*...*/ break; } } Bye, bearophile
Mar 06 2011
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday 06 March 2011 18:51:04 bearophile wrote:
 Bekenn:
 Final switch is really just meant to be used with enums; since
 enumeration values don't have to cover the whole range of possible base
 type values, and enumeration values don't often have a natural ordering,
 ranges make little sense there.

Thank you for your answer. If something doesn't have an ordering, then it's right to disallow the case range on it. But I'd like to be able to use case ranges in safer final switches on bytes/ubytes/chars. ------------------------- Jonathan M Davis:
Yeah. While I can see how you might want to use a final switch here, final
switches were really intended for enums,<

You often say that language features must pull their weight. Artificially restricting the usability of final switches to just enums makes them not pull their weight. There are times when I'd like to do this, but DMD is buggy here (I don't remember if I have already put this in Bugzilla): void main() { int x = 100; final switch (x % 3) { case 0: /*...*/ break; case 1: /*...*/ break; } }

I would say that it's actually fairly rare for you to even be _able_ to have a specific set of values which you could limit a final switch statement to. enum is the obvious case. Not only do you have a fixed set of values which the could be covered in by the case statements, but it's almost always buggy when you miss some. It's highly abnormal to want to have a case for each value of a byte or an integer or whatever. And while it's easy for a human to see that your example can only result in the values 0, 1, and 2, I'm not sure that it's so easy for the computer. Certainly, it would have to special case % and restrict it to primitive integral types. I expect that it would complicate final switch quite a bit to deal with anything other than enums, particularly since I don't think that that can really be generalized. I expect that final switch over enums is actually quite simple to implement. So, whether the additional complexity is worth what is likely a very rare thing to do for most programmers is debatable. As for pulling it's weight, I must definitely think that final switch pulls its weight for enums, just like disallowing ; as the body of a loop or conditional statement pulls its weight. It's a very simple feature which fixes a common set of bugs. If final switch could be reasonably expanded to cover more than enums, it may be worth it, but if it doesn't do that already, I question that it's worth it. Before you mentioned it, it certainly never occurred to me that anyone would want to. I've never seen anyone try to. The feature is sold completely on the idea of fixing bugs with missing cases for enums in switch statements. And that is _well_ worth it IMHO. If final switch doesn't do more than enums, and you think that it should, then by all means open up an enhancement request with suitable use cases as to why it would be useful, but I wouldn't expect it to be implemented. It seems to me that it would be complicating the implementation of final switch for minimal benefit. But it's not my decision to make anyway. It's Walter's. Now, if final switch actually compiles with anything other than an enum, then it needs to either stop compiling for anything which isn't an enum, or it needs to start working for non-enums, but I don't think that it was really intended to work for anything other than enums. - Jonathan M Davis
Mar 06 2011