Thread overview | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 17, 2006 Sets again | ||||
---|---|---|---|---|
| ||||
Well, with so much talk of features in (regexp) and out (bit), why not bring up my favourite yet again: the sets! Set are unordered arrays, that you can do union, intersect and difference operations on (And more). I have implemented sets as templates, but the syntax is cluncy, and well, optimisation is not that easy :/. We have all done this: if (((ch>='0')&&(ch<='9'))||((ch>='a')&&( ... and so on... With sets it is a much more straight forward aproach to this in reality simple problem: if (ch in <'0'..9, 'a'..'z', 'A'..'Z'>) { ... } Lets write a nice small example function: enum Weekday { MON, TUE, WED, THU, FRI, SAT, SUN }; set Weekdays { Weekday }; struct Employee { char[] name; Weekdays availableDays; } Weekdays weekdaysAvailableForAll(Employees[] employees) { Weekdays avilableDays = <MON..SUN>; // Weekdays.all ? foreach(Employee employee; emplouees) { availableDays -= employee.availableDays; } return vailableDays; } bool isDayGoodForAll(Weekday weekday, Employees[] employees) { return weekday in weekdaysAvailableForAll(employees); } If someone can propose a more clean, elegant, robust, usable, and optimisation friendly solution to this problem domain I stand corrected. But until then I say it is probably more useful to more people than complex math. Only problem I see is that set literals are even more needed than array literals. And then we have the problem, with: set Weekdays {Weekdays}; // and set Workdays {MON..FRI}; auto foo = <TUE, WED, FRI>; // Is this a Weekdays or a Workdays set? regards Fredrik Olsson |
February 17, 2006 Re: Sets again | ||||
---|---|---|---|---|
| ||||
Posted in reply to Fredrik Olsson | Sets are indeed a cool language feature. Perhaps some of the capability that you are looking for could be done with a template. The syntax could be something like ... if (i == Set!<int>(1, 3, 5..6, 8)) { ... } and with implicit function template instantiation: if(i == Set(1, 3, 5..6, 8)) { ... } What do you think? -Craig |
February 17, 2006 Re: Sets again | ||||
---|---|---|---|---|
| ||||
Posted in reply to Craig Black | Oops I'm too use to C++ template syntax. Minor correction: if (i == Set!(int)(1, 3, 5..6, 8)) { ... } |
February 17, 2006 Re: Sets again | ||||
---|---|---|---|---|
| ||||
Posted in reply to Craig Black | Craig Black skrev:
> Sets are indeed a cool language feature. Perhaps some of the capability that you are looking for could be done with a template. The syntax could be something like ...
>
> if (i == Set!<int>(1, 3, 5..6, 8)) { ... }
>
> and with implicit function template instantiation:
>
> if(i == Set(1, 3, 5..6, 8)) { ... }
>
> What do you think?
>
> -Craig
>
>
It works and I have some templates up and running for the purpose. But I see two major and obvious problems:
1. 5..6 is not possible as I can see it, and Set('a', 'b', 'c' ... is
well, hidious at best.
2. The implementation will probably never be as good as could be. For a
general purpose set I use an associative array with "bool[T] _set".
For a more limited set a bitfield is way more effective.
But I still stand by my point that sets are useful enough to have, that they should not be a template hack and putting them in a library. After all, sets are a primitive type of arrays (unordered arrays), and belong in the language, or not at all.
// Fredrik Olsson
|
February 17, 2006 Re: Sets again | ||||
---|---|---|---|---|
| ||||
Posted in reply to Fredrik Olsson | In article <dt54hb$alg$1@digitaldaemon.com>, Fredrik Olsson says... > >Well, with so much talk of features in (regexp) and out (bit), why not bring up my favourite yet again: the sets! > >Set are unordered arrays, that you can do union, intersect and difference operations on (And more). > >I have implemented sets as templates, but the syntax is cluncy, and well, optimisation is not that easy :/. > >We have all done this: >if (((ch>='0')&&(ch<='9'))||((ch>='a')&&( ... and so on... > >With sets it is a much more straight forward aproach to this in reality >simple problem: >if (ch in <'0'..9, 'a'..'z', 'A'..'Z'>) { ... } > >Lets write a nice small example function: > >enum Weekday { MON, TUE, WED, THU, FRI, SAT, SUN }; >set Weekdays { Weekday }; >struct Employee { > char[] name; > Weekdays availableDays; >} > >Weekdays weekdaysAvailableForAll(Employees[] employees) { > Weekdays avilableDays = <MON..SUN>; // Weekdays.all ? > foreach(Employee employee; emplouees) { > availableDays -= employee.availableDays; > } > return vailableDays; >} > >bool isDayGoodForAll(Weekday weekday, Employees[] employees) { > return weekday in weekdaysAvailableForAll(employees); >} > > >If someone can propose a more clean, elegant, robust, usable, and optimisation friendly solution to this problem domain I stand corrected. But until then I say it is probably more useful to more people than complex math. > >Only problem I see is that set literals are even more needed than array >literals. And then we have the problem, with: >set Weekdays {Weekdays}; // and >set Workdays {MON..FRI}; >auto foo = <TUE, WED, FRI>; // Is this a Weekdays or a Workdays set? > >regards > Fredrik Olsson Sets are cool. How about in for arrays for consistency with AA's: void foo(char[] ) { char[] arr = "abcdef"; //... if('d' in arr) { ... } } And perhaps when array operations are available: void main() { char[62] alphanum; alphanum[0..26] = 'a' + $index; alphanum[26..52] = alphanum[0..26] - 32; alphanum[52..62] = '0' + $index + 52; if('m' in alpha) { ... } } |
February 17, 2006 Re: Sets again | ||||
---|---|---|---|---|
| ||||
Posted in reply to Fredrik Olsson |
"Fredrik Olsson" <peylow@gmail.com> wrote..
> Craig Black skrev:
>> Sets are indeed a cool language feature. Perhaps some of the capability that you are looking for could be done with a template. The syntax could be something like ...
>>
>> if (i == Set!<int>(1, 3, 5..6, 8)) { ... }
>>
>> and with implicit function template instantiation:
>>
>> if(i == Set(1, 3, 5..6, 8)) { ... }
>>
>> What do you think?
>>
>> -Craig
> It works and I have some templates up and running for the purpose. But I see two major and obvious problems:
>
> 1. 5..6 is not possible as I can see it, and Set('a', 'b', 'c' ... is
> well, hidious at best.
> 2. The implementation will probably never be as good as could be. For a
> general purpose set I use an associative array with "bool[T] _set".
> For a more limited set a bitfield is way more effective.
>
> But I still stand by my point that sets are useful enough to have, that they should not be a template hack and putting them in a library. After all, sets are a primitive type of arrays (unordered arrays), and belong in the language, or not at all.
Aye. Even rudimentary Set support within the grammar would be really useful. Pascal was just a tuition tool, but it did have Sets ~ that almost made up for a number of deficiencies.
|
February 17, 2006 Re: Sets again | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dave | Dave wrote: > In article <dt54hb$alg$1@digitaldaemon.com>, Fredrik Olsson says... > >>Well, with so much talk of features in (regexp) and out (bit), why not bring up my favourite yet again: the sets! >> >>Set are unordered arrays, that you can do union, intersect and difference operations on (And more). >> >>I have implemented sets as templates, but the syntax is cluncy, and well, optimisation is not that easy :/. >> >>We have all done this: >>if (((ch>='0')&&(ch<='9'))||((ch>='a')&&( ... and so on... >> >>With sets it is a much more straight forward aproach to this in reality simple problem: >>if (ch in <'0'..9, 'a'..'z', 'A'..'Z'>) { ... } >> >>Lets write a nice small example function: >> >>enum Weekday { MON, TUE, WED, THU, FRI, SAT, SUN }; >>set Weekdays { Weekday }; >>struct Employee { >> char[] name; >> Weekdays availableDays; >>} >> >>Weekdays weekdaysAvailableForAll(Employees[] employees) { >> Weekdays avilableDays = <MON..SUN>; // Weekdays.all ? >> foreach(Employee employee; emplouees) { >> availableDays -= employee.availableDays; >> } >> return vailableDays; >>} >> >>bool isDayGoodForAll(Weekday weekday, Employees[] employees) { >> return weekday in weekdaysAvailableForAll(employees); >>} >> >> >>If someone can propose a more clean, elegant, robust, usable, and optimisation friendly solution to this problem domain I stand corrected. But until then I say it is probably more useful to more people than complex math. >> >>Only problem I see is that set literals are even more needed than array literals. And then we have the problem, with: >>set Weekdays {Weekdays}; // and >>set Workdays {MON..FRI}; >>auto foo = <TUE, WED, FRI>; // Is this a Weekdays or a Workdays set? >> >>regards >> Fredrik Olsson > > > Sets are cool. > > How about in for arrays for consistency with AA's: > Yes please :) This is so obviously missing :) > void foo(char[] ) > { > char[] arr = "abcdef"; > //... > if('d' in arr) { ... } > } > |
February 17, 2006 Re: Sets again | ||||
---|---|---|---|---|
| ||||
Posted in reply to Fredrik Olsson Attachments: | Fredrik Olsson wrote:
> Well, with so much talk of features in (regexp) and out (bit), why not bring up my favourite yet again: the sets!
>
> Set are unordered arrays, that you can do union, intersect and difference operations on (And more).
>
> I have implemented sets as templates, but the syntax is cluncy, and well, optimisation is not that easy :/.
>
> We have all done this:
> if (((ch>='0')&&(ch<='9'))||((ch>='a')&&( ... and so on...
>
> With sets it is a much more straight forward aproach to this in reality
> simple problem:
> if (ch in <'0'..9, 'a'..'z', 'A'..'Z'>) { ... }
>
> Lets write a nice small example function:
>
> enum Weekday { MON, TUE, WED, THU, FRI, SAT, SUN };
> set Weekdays { Weekday };
> struct Employee {
> char[] name;
> Weekdays availableDays;
> }
>
> Weekdays weekdaysAvailableForAll(Employees[] employees) {
> Weekdays avilableDays = <MON..SUN>; // Weekdays.all ?
> foreach(Employee employee; emplouees) {
> availableDays -= employee.availableDays;
> }
> return vailableDays;
> }
>
> bool isDayGoodForAll(Weekday weekday, Employees[] employees) {
> return weekday in weekdaysAvailableForAll(employees);
> }
>
>
> If someone can propose a more clean, elegant, robust, usable, and optimisation friendly solution to this problem domain I stand corrected. But until then I say it is probably more useful to more people than complex math.
>
> Only problem I see is that set literals are even more needed than array
> literals. And then we have the problem, with:
> set Weekdays {Weekdays}; // and
> set Workdays {MON..FRI};
> auto foo = <TUE, WED, FRI>; // Is this a Weekdays or a Workdays set?
>
> regards
> Fredrik Olsson
Probably not entirely what you are after, but what the hell....here is the set class I use on occaision( hope this is the latest version..).
-DavidM
|
February 17, 2006 Re: Sets again | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ivan Senji | Ivan Senji wrote:
> Dave wrote:
>
>> In article <dt54hb$alg$1@digitaldaemon.com>, Fredrik Olsson says...
>>
>>> Well, with so much talk of features in (regexp) and out (bit), why not bring up my favourite yet again: the sets!
>>>
>>> Set are unordered arrays, that you can do union, intersect and difference operations on (And more).
>>>
>>> I have implemented sets as templates, but the syntax is cluncy, and well, optimisation is not that easy :/.
>>>
>>> We have all done this:
>>> if (((ch>='0')&&(ch<='9'))||((ch>='a')&&( ... and so on...
>>>
>>> With sets it is a much more straight forward aproach to this in reality simple problem:
>>> if (ch in <'0'..9, 'a'..'z', 'A'..'Z'>) { ... }
>>>
>>> Lets write a nice small example function:
>>>
>>> enum Weekday { MON, TUE, WED, THU, FRI, SAT, SUN };
>>> set Weekdays { Weekday };
>>> struct Employee {
>>> char[] name;
>>> Weekdays availableDays;
>>> }
>>>
>>> Weekdays weekdaysAvailableForAll(Employees[] employees) {
>>> Weekdays avilableDays = <MON..SUN>; // Weekdays.all ?
>>> foreach(Employee employee; emplouees) {
>>> availableDays -= employee.availableDays;
>>> }
>>> return vailableDays;
>>> }
>>>
>>> bool isDayGoodForAll(Weekday weekday, Employees[] employees) {
>>> return weekday in weekdaysAvailableForAll(employees);
>>> }
>>>
>>>
>>> If someone can propose a more clean, elegant, robust, usable, and optimisation friendly solution to this problem domain I stand corrected. But until then I say it is probably more useful to more people than complex math.
>>>
>>> Only problem I see is that set literals are even more needed than array literals. And then we have the problem, with:
>>> set Weekdays {Weekdays}; // and
>>> set Workdays {MON..FRI};
>>> auto foo = <TUE, WED, FRI>; // Is this a Weekdays or a Workdays set?
>>>
>>> regards
>>> Fredrik Olsson
>>
>>
>>
>> Sets are cool.
>>
>> How about in for arrays for consistency with AA's:
>>
>
> Yes please :) This is so obviously missing :)
>
>> void foo(char[] )
>> {
>> char[] arr = "abcdef";
>> //...
>> if('d' in arr) { ... }
>> }
>>
Having sets would indeed be useful. In particular if you could have sets of integers, or even better, arbitrary types.
|
February 18, 2006 Re: Sets again | ||||
---|---|---|---|---|
| ||||
Posted in reply to Fredrik Olsson | Please guys .. let's not try to put everything in the language. It all can be implemented using classes (and templates, if you really want). Building everything into D will just turn D into another C++. What I mean is, it'll become a kludge. Fredrik Olsson wrote: > Well, with so much talk of features in (regexp) and out (bit), why not bring up my favourite yet again: the sets! > > Set are unordered arrays, that you can do union, intersect and difference operations on (And more). > > I have implemented sets as templates, but the syntax is cluncy, and well, optimisation is not that easy :/. > > We have all done this: > if (((ch>='0')&&(ch<='9'))||((ch>='a')&&( ... and so on... > > With sets it is a much more straight forward aproach to this in reality simple problem: > if (ch in <'0'..9, 'a'..'z', 'A'..'Z'>) { ... } Well, this really is a range problem. if( ch.inrange('0','9') ) { .... } > > Lets write a nice small example function: > > enum Weekday { MON, TUE, WED, THU, FRI, SAT, SUN }; > set Weekdays { Weekday }; > struct Employee { > char[] name; > Weekdays availableDays; > } > > Weekdays weekdaysAvailableForAll(Employees[] employees) { > Weekdays avilableDays = <MON..SUN>; // Weekdays.all ? > foreach(Employee employee; emplouees) { > availableDays -= employee.availableDays; > } > return vailableDays; > } > > bool isDayGoodForAll(Weekday weekday, Employees[] employees) { > return weekday in weekdaysAvailableForAll(employees); > } > > > If someone can propose a more clean, elegant, robust, usable, and optimisation friendly solution to this problem domain I stand corrected. I believe that a proper object oriented implementation is certainly possible. > But until then I say it is probably more useful to more people than complex math. I don't use either of them, I find the need for other things (i.e. standard Collection Classes) to be more urgent, but that's just me. > > Only problem I see is that set literals are even more needed than array literals. And then we have the problem, with: > set Weekdays {Weekdays}; // and > set Workdays {MON..FRI}; > auto foo = <TUE, WED, FRI>; // Is this a Weekdays or a Workdays set? I think auto type inference wasn't a good idea anyway. > > regards > Fredrik Olsson |
Copyright © 1999-2021 by the D Language Foundation