shouting versus dotting

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Sun Oct 5 17:27:54 PDT 2008


Denis Koroskin wrote:
> On Mon, 06 Oct 2008 04:03:08 +0400, Andrei Alexandrescu 
> <SeeWebsiteForEmail at erdani.org> wrote:
> 
>> Jason House wrote:
>>> Andrei Alexandrescu wrote:
>>>
>>>> Leandro Lucarella wrote:
>>>>> "enum" as the way to declare manifest constants were much more ugly 
>>>>> than
>>>>> "!(", and most of the people were against it. I don't see why ".(" 
>>>>> should
>>>>> be introduced.
>>>> Ugly or not, enumerated symbols were manifest constants to begin with.
>>>> That's kinda hard to argue against because it's a sheer fact.
>>>  Even before we expanded enums, I hated how there was no toString() 
>>> for enum
>>> types.
>>
>> defineEnum in std.typecons provides that (and parsing too).
>>
>>> Walter explained this was because bit masks made it difficult. I
>>> like using enums for a restricted set of options.  That'd allow the
>>> compiler to provide toString and catch misuse in switch statements...
>>> Including when I add or remove allowed values.
>>
>> Walter hasn't gotten around to implementing the final switch 
>> statement, which does exactly as you mention. For the interested I 
>> paste the relevant section in TDPL - hot off the oven:
>>
>> \section{The \protect\cc{final switch} Statement}
>>
>> It is  often the case  that @switch@ is  meant to handle  all possible
>> cases,  such as  all values  of a  small integer  or of  an enumerated
>> type. If, during maintenance, the  number of cases is changing, all of
>> the dependent @switch@  statements suddenly fall out of  sync and must
>> be  manually searched  for  and modified.   For  such situations,  the
>> \cc{final switch} statement comes in handy:
>>
>> \begin{D}
>> enum deviceStatusMask = 3;
>> ...
>> void Handle(uint x) {
>>    final switch (x & deviceStatusMask) {
>>    case 0: ...
>>    case 1: ...
>>    case 2: ...
>>    case 3: ...
>>    }
>> }
>> \end{D}
>>
>> Should  the value of  @mask@ change  later to,  say, 7,  attempting to
>> recompile @Handle@ is met with refusal on the following grounds:
>>
>> \begin{lstlisting}[language=sys]
>> Error: final switch statement must handle all values
>> \end{lstlisting}
>>
>> The \cc{final switch} statement looks  at the shape of its controlling
>> expression to figure out the bounds, as follows:
>>
>> \begin{itemize*}
>> \item  If \meta{expression}  is \metai{e}  @&@ \metaii{e}  and  one of
>>    \metai{e} and \metaii{e} evaluates  to a positive compile-time value
>>    @c@, then the range is determined as @0@ up to (and including) @c at .
>> \item  If  \meta{expression}   is  \metai{e}  \cc{\%}  \metaii{e}  and
>>    \metaii{e} evaluates to a  positive compile-time value @c@, then the
>>    range is determined as @0@ up to (and not including) \cc{c}.
>> \item  If  \meta{expression}  is   an  unsigned  right  shift  (either
>>    \metai{e}  \cc{>>}  \metaii{e}  operating  on unsigned  numbers,  or
>>    \metai{e}  \cc{>>>} \metaii{e}),  and if  \metaii{e} evaluates  to a
>>    compile-time value  @c@, then the range  is determined as  @0@ up to
>>    (and not including) \cc{1 << (8 *} \metai{e}\cc{.sizeof - c)}.%>>
>> \item If  \meta{expression} is  the assignment variant  of one  of the
>>    above  (@&=@, \cc{\%=}  etc.) then  the range  the same  as  for the
>>    non-assignment variant.
>> \item If  \meta{expression} is  an enumerated type,  the range  is the
>>    entire set of values of the enumerated type.
>> \item   Otherwise,  the  range   is  @e.min@   up  to   and  including
>>    @e.max at . (The @min@ and @max@  constants are defined for all numeric
>>    types.)
>> \end{itemize*}
>>
>> There are quite a few other  cases in which the range of an expression
>> could be  effectively determined,  but \cc{final switch}  only handles
>> the  usual ones.   A @default@  label  is allowed  inside a  \cc{final
>>    switch} statement  and practically turns  off all checks  because it
>> ensures \emph{de facto} that all values are handled.
>>
>>
>> Andrei
> 
> Final switch is great, but why allow default case in it? Putting the 
> default case into the final switch effectively transforms it into a 
> regular one discarding all of its benefits. What's the point?

Good point. I was thinking of making maintenance easier: sometimes you 
decide to insert a default. Then you'd need to wipe the "final" too. 
Then you comment out the default. You'd need to add the "final" back 
(and you may forget). And so on.

Andrei



More information about the Digitalmars-d mailing list