www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Range and set.

reply Fredrik Olsson <peylow gmail.com> writes:
Before I start I better say it out load; I am a Pascal programmer.

I use Pascal because it helps me write correct code and allows me to 
write a buffer overflow vulnerability if I like. Much like D does, but D 
has a more modern touch to it that I start to like very much.

Anyway, two powerfull basic types in Pascal that I use all the time as 
they generate so nice compiler/runtime errors when debugging my 
applications, and in general gives more functionality with less code, 
are ranges and sets.

D already sort of have ranges in a pseudo form in slices. Sets is not 
present at all but are too usefull to be omiited :). I think it would be 
great to build upon. And I think the syntax would be natural.

I give some pseudo-code for how it could be implemented and what it can 
be good for. This code could be even more compact given the strength of 
ranges and sets, but I go for clarity :).


module foobar;

import std.stdio;

enum Day { MON, TUE, WED, THU, FRI, SAT, SUN }
set Days { Day }
range WeekDay { MON..FR }

int main(char[][] args) {
// Let people be an associative array of Days, where each element
// represent the week days a person is available (as a set).
   Days[char[]] people;
   people["John"] = [MON..WED, FRI..SUN];
   people["Sally"] = [TUE, FRI..SAT];

// Let free be a Days set, and set all values.
   Days free = [Day];


// Iterate all persons and remove busy days from the free set.
   foreach (Days days; people) {
     free *= days;  // * is intersect, + is union and - is difference.
   }

// Prefer weekdays, remove days in weekend if any weekday is available
// A set is false if empty, and true if contains one or more values.
   if (free * [WeekDay]) {
     free *= WeekDays;
   }

// If the resulting set is empty to bad, else write out possible days.
   if (free == []) {
     writefln("No possible free days for all people.");
   } else {
     writef("Possible free days are:);
   // Foreach on a set should loop over all contained values
     foreach (Day day; allAvailable) {
       char[][Day.max] daynames = ["monday", "tuesday", "wednesday",
           "thursday", "friday", "saturday", "sunday"];
       writef(" " ~ daynames[day]);
     }
     writefln(".");
   }
}

The output of this program would naturaly be:
Possible free days are: tuesday friday.


For optimum usability range checks should be enforced on enums, ranges 
and sets. So that assigning for example 42 to the Day enum or adding 12 
to the Days set would cause a range check error. Only problem here is 
backward compatibility (Especially old C code), so maybe "strict" (Or 
some other better suitable word) could be added as a keyword, example:
strict enum Foo { BAR, BAZ }
To indicate that an enum, range or set should be range checked?

For small sets (64 values or less with no spread) some operator 
overloading, a struct and typedefs could be used to simulate all this. 
But for larger sets (and better performance?) making it into the core of 
the language makes just as much sense as strings and complex numbers.

regards
	Fredrik Olsson
Aug 06 2005
parent "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Fredrik Olsson" <peylow gmail.com> wrote in message 
news:dd35k1$21r3$1 digitaldaemon.com...
 Before I start I better say it out load; I am a Pascal programmer.

 I use Pascal because it helps me write correct code and allows me to write 
 a buffer overflow vulnerability if I like. Much like D does, but D has a 
 more modern touch to it that I start to like very much.

 Anyway, two powerfull basic types in Pascal that I use all the time as 
 they generate so nice compiler/runtime errors when debugging my 
 applications, and in general gives more functionality with less code, are 
 ranges and sets.

I believe sets in Pascal are implemented as bit arrays (hence the restrictions on the types to ordinal types). So with a slightly different syntax you can probably get most of Pascal's sets with bit arrays. For example a set of chars would be bit[char.max]. You'd have to write union/intersection/etc specially but that doesn't seem hard. For example enum Day { MON, TUE, WED, THU, FRI, SAT, SUN } typedef bit[Day.max] Days; Days schedule; schedule[Day.MON .. Day.THU] = true; // recall D slicing is not inclusive if (schedule[Day.FRI]) {...}
Aug 07 2005