Re: final switch and straight integers

2016-04-21 Thread Marc Schütz via Digitalmars-d
On Thursday, 21 April 2016 at 12:45:34 UTC, Steven Schveighoffer 
wrote:

On 4/19/16 6:04 PM, Stefan Koch wrote:
On Tuesday, 19 April 2016 at 14:53:18 UTC, Steven 
Schveighoffer wrote:



or we
should do away with requiring handling all enum cases.



Are you suggesting getting rid of final switch ?


No, what I'm suggesting is that final switch behave 
consistently. For integers, final switch doesn't require all 
possible values be handled, but for enums it does. One way to 
make this consistent is to not require all enums be handled. 
I'm not suggesting that this is the best answer, just that it 
is a possible way to square the inconsistency.


Note that even with final switch on an enum, you have issues, 
especially if the enum is considered to be a bitfield:


enum bitfield {
   flag1 = 1 << 0,
   flag2 = 1 << 1
}


`final enum` was suggested for strict enums that can't be used as 
flags. If we had that, we could phase out `final switch` on 
non-strict enums.


Re: final switch and straight integers

2016-04-21 Thread Steven Schveighoffer via Digitalmars-d

On 4/20/16 4:23 AM, Johan Engelen wrote:

On Wednesday, 20 April 2016 at 06:36:01 UTC, bearophile wrote:


It's easy to cover all the values in a switch, using ranges.


Not as easy as you would think:
 int i;
 switch(i) {
 case 0: .. case 9:
 break;
 case 10: ..case 1000:
 break;
 default:
 break;
 }
-->  Error: had 990 cases which is more than 256 cases in case range

The FE always lowers CaseRangeStatements into a list of CaseStatements,
so LDC currently has the same limitation.



Um... this seems a horrid limitation.

-Steve


Re: final switch and straight integers

2016-04-21 Thread Steven Schveighoffer via Digitalmars-d

On 4/19/16 6:04 PM, Stefan Koch wrote:

On Tuesday, 19 April 2016 at 14:53:18 UTC, Steven Schveighoffer wrote:


or we
should do away with requiring handling all enum cases.



Are you suggesting getting rid of final switch ?


No, what I'm suggesting is that final switch behave consistently. For 
integers, final switch doesn't require all possible values be handled, 
but for enums it does. One way to make this consistent is to not require 
all enums be handled. I'm not suggesting that this is the best answer, 
just that it is a possible way to square the inconsistency.


Note that even with final switch on an enum, you have issues, especially 
if the enum is considered to be a bitfield:


enum bitfield {
   flag1 = 1 << 0,
   flag2 = 1 << 1
}

...

void foo(bitfield x)
final switch(x)
{
   case flag1:
 writeln("flag1");
 break;
   case flag2:
 writeln("flag2");
 break;
}

This compiles, but doesn't handle flag1 | flag2. So final switch isn't 
helping to cover all cases.


In other cases, you may have a member of an enum that isn't ever used as 
a value, but you have to cover it:


enum message {
foo,
bar,
mask = foo | bar
}

final switch is nice when you fit into the use case. When not, you have 
to fall back to normal switch. I find many times wanting to use final 
switch but having to follow the rules would make it look silly.


-Steve


Re: final switch and straight integers

2016-04-21 Thread Dominikus Dittes Scherkl via Digitalmars-d

On Wednesday, 20 April 2016 at 17:42:03 UTC, Basile Burg wrote:
On Wednesday, 20 April 2016 at 10:19:17 UTC, Dominikus Dittes 
Scherkl wrote:


Anyway, something need to be changed.
a) allow Range Cases (nice for ints but bad idea for enums)
b) require also non-enum types to explicitly state all cases 
(bad idea for any multi-byte type, even near useless for 
single bytes)

c) forbid other types than enum in final switch

I strongly vote for (c).


A good `int` value for a variable `int x` can be enforced 
(min(), max(), clamping, warping, etc) **before** a final 
switch(x).
No, because final switch requires you to enumerate all possible 
cases.
If c) is done then the compiler in this cas would disallow 
something that's completly safe (generally speaking I mean, 
here safe == no SwitchException possible).
Why would you ever want to use final switch on int? Why not 
simply use the normal switch? Especially if you enforced a useful 
range with min(), max(), etc. would it not be better to do the 
remaining cases manually? (or even do the range check in the 
default case?)




Re: final switch and straight integers

2016-04-20 Thread Basile Burg via Digitalmars-d
On Wednesday, 20 April 2016 at 10:19:17 UTC, Dominikus Dittes 
Scherkl wrote:


Anyway, something need to be changed.
a) allow Range Cases (nice for ints but bad idea for enums)
b) require also non-enum types to explicitly state all cases 
(bad idea for any multi-byte type, even near useless for single 
bytes)

c) forbid other types than enum in final switch

I strongly vote for (c).


A good `int` value for a variable `int x` can be enforced (min(), 
max(), clamping, warping, etc) **before** a final switch(x). If 
c) is done then the compiler in this cas would disallow something 
that's completly safe (generally speaking I mean, here safe == no 
SwitchException possible).


Re: final switch and straight integers

2016-04-20 Thread Dominikus Dittes Scherkl via Digitalmars-d

On Wednesday, 20 April 2016 at 07:23:09 UTC, Bastiaan Veelo wrote:
On Wednesday, 20 April 2016 at 07:18:55 UTC, Bastiaan Veelo 
wrote:

On Wednesday, 20 April 2016 at 06:36:01 UTC, bearophile wrote:

Dominikus Dittes Scherkl:

final switch makes no sense on things that are not 
enumerated. Even on ubyte almost nobody will ever list all 
256 cases, not to mention larger types.


It's easy to cover all the values in a switch, using ranges.


2. No CaseRangeStatements are allowed.


Sorry, pressed Send too early. You mean implement to remove the 
above limitation?


Anyway, something need to be changed.
a) allow Range Cases (nice for ints but bad idea for enums)
b) require also non-enum types to explicitly state all cases (bad 
idea for any multi-byte type, even near useless for single bytes)

c) forbid other types than enum in final switch

I strongly vote for (c).


Re: final switch and straight integers

2016-04-20 Thread Johan Engelen via Digitalmars-d

On Wednesday, 20 April 2016 at 06:36:01 UTC, bearophile wrote:


It's easy to cover all the values in a switch, using ranges.


Not as easy as you would think:
int i;
switch(i) {
case 0: .. case 9:
break;
case 10: ..case 1000:
break;
default:
break;
}
-->  Error: had 990 cases which is more than 256 cases in 
case range


The FE always lowers CaseRangeStatements into a list of 
CaseStatements, so LDC currently has the same limitation.




Re: final switch and straight integers

2016-04-20 Thread Bastiaan Veelo via Digitalmars-d

On Wednesday, 20 April 2016 at 07:18:55 UTC, Bastiaan Veelo wrote:

On Wednesday, 20 April 2016 at 06:36:01 UTC, bearophile wrote:

Dominikus Dittes Scherkl:

final switch makes no sense on things that are not 
enumerated. Even on ubyte almost nobody will ever list all 
256 cases, not to mention larger types.


It's easy to cover all the values in a switch, using ranges.


2. No CaseRangeStatements are allowed.


Sorry, pressed Send too early. You mean implement to remove the 
above limitation?


Re: final switch and straight integers

2016-04-20 Thread Bastiaan Veelo via Digitalmars-d

On Wednesday, 20 April 2016 at 06:36:01 UTC, bearophile wrote:

Dominikus Dittes Scherkl:

final switch makes no sense on things that are not enumerated. 
Even on ubyte almost nobody will ever list all 256 cases, not 
to mention larger types.


It's easy to cover all the values in a switch, using ranges.


2. No CaseRangeStatements are allowed.


Re: final switch and straight integers

2016-04-20 Thread bearophile via Digitalmars-d

Dominikus Dittes Scherkl:

final switch makes no sense on things that are not enumerated. 
Even on ubyte almost nobody will ever list all 256 cases, not 
to mention larger types.


It's easy to cover all the values in a switch, using ranges. No 
need to forbid final switch for integral values. It just needs to 
be implemented correctly.


Bye,
bearophile


Re: final switch and straight integers

2016-04-19 Thread Dominikus Dittes Scherkl via Digitalmars-d

On Tuesday, 19 April 2016 at 22:04:21 UTC, Stefan Koch wrote:
On Tuesday, 19 April 2016 at 14:53:18 UTC, Steven Schveighoffer 
wrote:



or we
should do away with requiring handling all enum cases.



Are you suggesting getting rid of final switch ?


No - I think he suggests to error out if final switch is used on 
something other than enums.


I support this suggestion, final switch makes no sense on things 
that are not enumerated. Even on ubyte almost nobody will ever 
list all 256 cases, not to mention larger types.


Re: final switch and straight integers

2016-04-19 Thread Stefan Koch via Digitalmars-d
On Tuesday, 19 April 2016 at 14:53:18 UTC, Steven Schveighoffer 
wrote:



or we
should do away with requiring handling all enum cases.



Are you suggesting getting rid of final switch ?




final switch and straight integers

2016-04-19 Thread Steven Schveighoffer via Digitalmars-d
I was surprised that in my code, I had a final switch on an integer, and 
compiler never complained.


I looked at the rules here: 
http://dlang.org/spec/statement.html#final-switch-statement


Rules are:

1. No DefaultStatement is allowed.
2. No CaseRangeStatements are allowed.
3. If the switch Expression is of enum type, all the enum members 
must appear in the CaseStatements.
4. The case expressions cannot evaluate to a run time initialized 
value.


What if expression is not of enum type? Apparently that just means no 
default statement is required.


In other words:

void foo(int x)
{
   final switch(x) {
  case 0:
 break;
   }
}

compiles. I was surprised about this, apparently it just means throw an 
error if no case is matched. I don't see a lot of value in this over a 
straight switch statement. Is there something I'm missing?


I find this inconsistent with the enum version -- shouldn't I have to 
handle all possible values? I think either rule 3 should remove the 
qualifier "If the expression is of enum type" and qualify rule 2 which 
only would make sense for enums, or we should do away with requiring 
handling all enum cases.


-Steve