Wrong enum comparisons

Marco Leise Marco.Leise at gmx.de
Mon May 28 11:47:46 PDT 2012


Am Mon, 28 May 2012 13:48:23 +0200
schrieb "Araq" <rumpf_a at web.de>:

> Pascal got type safe enums and sets of enums (aka "flags") right 
> in the 60ies. Too bad not even Ada copied this nice feature. 
> Fortunately, Nimrod does.

Yes, I really like Pascal for that feature. Actually it is a mix of features I miss from Pascal in D:

1. Ranged ordinal types

  type Month = 1 .. 12;
  type AsciiLower = 'a' .. 'z';
  type Hours = 0 .. 24;

As far as I remember it, the compiler chooses the optimal ordinal type derived from the start and end constant. It is a form of self-documenting code and it could work nice with "checked integers", if they are ever implemented in D.


2. Enumerations

  type Day = ( Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday );

Ord(x) gives the ordinal value of an enumeration variable, e.g. neither implicit conversion to integer types nor casts, but a language defined, clean way to convert from enums to their inherent integer representation.


3. Sets

I'd like to start with the enumeration for the days of a week, because I think both Pascal and D look intuitive here:

  Pascal:
    type Day = ( Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday );
    var weekday : Day;
    weekday = Monday;
    weekday = Succ(weekday); // Tuesday
  D:
    enum Day { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday }
    Day weekday = Monday;
    weekday++; // Tuesday

But D lacks proper sets, which turn any enumeration into a set:

    type 
      DaySet = set of Day;

Note how Pascal naturally maps the enum values (0 through 6) to 1, 2, 4, 8, 16, 32 and 64 internally, while in C or D you need to do this manually or by importing a module that offers a template solution. Further you can apply the typical operators to sets:

    var
      workdays : DaySet;
    workdays = [ Monday .. Friday ];  // pretty nice shortcut to set a range of flags
    if Monday in workdays then ...    // check if set contains a value
    weekdays = weekdays + [ Monday, Sunday ] // union (adds Sunday)
    weekdays = weekdays - [ Monday, Sunday ] // complement (removes Monday)
    weekdays = weekdays * [ Monday, Sunday ] // intersection (leaves Monday)
    // (in)euqality, subset and superset are also implemented

I think flag sets are needed often enough (file open modes, drawing hints, enabled features) to warrant that feature and they enable some programming styles that are awkward with what C gives you at hand.


123. All these integrate nicely with each other

Create an array that holds a value of 0 to 24 for each week day:

  var hoursPerDay : array[Day] of Hours;
  hoursPerDay[Monday] = 8;

In general I had a good experience with Pascal when it comes to defining and checking flags.

-- 
Marco



More information about the Digitalmars-d mailing list