digitalmars.D - Datatypes I miss
- Fredrik Olsson (67/67) Dec 07 2005 Ranges and sets :).
- Tom (7/74) Dec 07 2005 I don't know about set or about the syntax but the range idea is also so...
- James Dunne (12/93) Dec 07 2005 The only potential problem I can see in this is a conflict with static
- Fredrik Olsson (13/28) Dec 08 2005 Yes, it is a quite huge problem I guess as well. I remember reading in
- Don Clugston (26/40) Dec 08 2005 I think there are TWO things going on here.
- BCS (3/18) Dec 08 2005 Sweet! This would be great!
- Bruno Medeiros (21/70) Dec 09 2005 That invariant in the middle of the typedef declaration seems a bit out
- Bruno Medeiros (6/21) Dec 09 2005 And yes, the similarity to structs is something worth to note. Hum..
- Lionello Lunesu (13/15) Dec 12 2005 Right, it's like a struct that inherits from a basic type, isn't it?
- BCS (4/24) Dec 09 2005 I like the idea. It has my vote. For trivial types that need math ops it...
- David Medlock (13/94) Dec 09 2005 Do you mean you miss them from Pascal?
- Fredrik Olsson (8/17) Dec 09 2005 No coincident at all :). I am a Pascal fan as well, and Lisp fan, and
- James Dunne (3/27) Dec 09 2005 You actually /LIKE/ SQL?
- David Medlock (5/36) Dec 09 2005 SQL is reasonably laid out, and can be readily optimized since it is a
- Fredrik Olsson (9/28) Dec 14 2005 SQL appeals to me because of it's small set of functionally that allows
- Glen Perkins (28/56) Dec 10 2005 I find ranges and sets and tuples and other such Lispy datatypes extreme...
Ranges and sets :). This is me more or less having a fantasy. Ranges and sets are without competition the two data types I use the most. They make writing solid code so much easy, helps finding range errors while debugging and reduces code size in general. Both fits quite nicely into existing functionality in D, as well as into the paradigm of making usable functionality part of the core language (as for complex numbers and strings). Ranges are semi there when slicing arrays, and sets can be emulates with associative arrays with somewhat awkward syntax. Anyway, if my x-mas wish comes true then :); RangeDeclaration: range [Identifier] [: RangeBaseType] [RangeBody] RangeBaseType: IntegerType RangeBody: RangeMember RangeMember: AssignExpression .. AssignExpression For example: range minute 0..59; // Static range minute = 61; // Exception if compiling with range checks range slice: uint; // Dynamic range; int[12] foo; slice = 2..foo.length-2; int[] bar = foo[slice]; Range properties would be .min, .max, .length and naturally .sizeof Constant ranges are written with the .. operator just as one writes slices now. One minor hitch here, as slicing for arrays has the upper bound not including and having the upper bound not including for proper ranges would be awkward. But then again I have more often tried using foo[$] to get the last element of an array and failed, then I have ever used foo[2..$] to get the last elements. Naturally the operator in should be able to work with ranges so that one could do for example: if (mychar in 'a'..'z') { ... } while (somenumber in 1..42) { ... } And then sets: SetDeclaration: set [Identifier] SetBody SetBaseType: IntegerType SetBody: IntegerType EnumType RangeType { SetMembers } SetMembers SetMember [, SetMembers] SetMember: AssignExpression RangeMember SetType // To expand existing sets For example: set alfa {'A'..'Z', 'a'..'z'}; set alfanum { alfa, '0'-'9' }; enum weekday { MON, TUE, WED, THU, FRI, SAT, SUN }; set weekdays weekday; weekdays freedays = [TUE..THU, SAT]; if (selectedday in freedays) { ... } I mean how many of us have not written: if (tolower(ch) >= 'a' && tolower(ch) <= 'z' && ch >= '0' && ch <= '9') { ... } And even longer when writing for non English. This is much nicer: if (toupper(ch) in ['A'..'Z', '0'..'9']) { ... } And a compiler can optimize easy to just test bits.
Dec 07 2005
I don't know about set or about the syntax but the range idea is also something I had wished for so long. It's very common to use integers just in a specified range, it'd make code much more nicer. Also the string enum would be very nice (or maybe something more general). I don't think all this could be implemented from a day to another but who knows in some future :D In article <dn6re3$ckq$1 digitaldaemon.com>, Fredrik Olsson says...Ranges and sets :). This is me more or less having a fantasy. Ranges and sets are without competition the two data types I use the most. They make writing solid code so much easy, helps finding range errors while debugging and reduces code size in general. Both fits quite nicely into existing functionality in D, as well as into the paradigm of making usable functionality part of the core language (as for complex numbers and strings). Ranges are semi there when slicing arrays, and sets can be emulates with associative arrays with somewhat awkward syntax. Anyway, if my x-mas wish comes true then :); RangeDeclaration: range [Identifier] [: RangeBaseType] [RangeBody] RangeBaseType: IntegerType RangeBody: RangeMember RangeMember: AssignExpression .. AssignExpression For example: range minute 0..59; // Static range minute = 61; // Exception if compiling with range checks range slice: uint; // Dynamic range; int[12] foo; slice = 2..foo.length-2; int[] bar = foo[slice]; Range properties would be .min, .max, .length and naturally .sizeof Constant ranges are written with the .. operator just as one writes slices now. One minor hitch here, as slicing for arrays has the upper bound not including and having the upper bound not including for proper ranges would be awkward. But then again I have more often tried using foo[$] to get the last element of an array and failed, then I have ever used foo[2..$] to get the last elements. Naturally the operator in should be able to work with ranges so that one could do for example: if (mychar in 'a'..'z') { ... } while (somenumber in 1..42) { ... } And then sets: SetDeclaration: set [Identifier] SetBody SetBaseType: IntegerType SetBody: IntegerType EnumType RangeType { SetMembers } SetMembers SetMember [, SetMembers] SetMember: AssignExpression RangeMember SetType // To expand existing sets For example: set alfa {'A'..'Z', 'a'..'z'}; set alfanum { alfa, '0'-'9' }; enum weekday { MON, TUE, WED, THU, FRI, SAT, SUN }; set weekdays weekday; weekdays freedays = [TUE..THU, SAT]; if (selectedday in freedays) { ... } I mean how many of us have not written: if (tolower(ch) >= 'a' && tolower(ch) <= 'z' && ch >= '0' && ch <= '9') { ... } And even longer when writing for non English. This is much nicer: if (toupper(ch) in ['A'..'Z', '0'..'9']) { ... } And a compiler can optimize easy to just test bits.Tom
Dec 07 2005
Fredrik Olsson wrote:Ranges and sets :). This is me more or less having a fantasy. Ranges and sets are without competition the two data types I use the most. They make writing solid code so much easy, helps finding range errors while debugging and reduces code size in general. Both fits quite nicely into existing functionality in D, as well as into the paradigm of making usable functionality part of the core language (as for complex numbers and strings). Ranges are semi there when slicing arrays, and sets can be emulates with associative arrays with somewhat awkward syntax. Anyway, if my x-mas wish comes true then :); RangeDeclaration: range [Identifier] [: RangeBaseType] [RangeBody] RangeBaseType: IntegerType RangeBody: RangeMember RangeMember: AssignExpression .. AssignExpression For example: range minute 0..59; // Static range minute = 61; // Exception if compiling with range checks range slice: uint; // Dynamic range; int[12] foo; slice = 2..foo.length-2; int[] bar = foo[slice]; Range properties would be .min, .max, .length and naturally .sizeof Constant ranges are written with the .. operator just as one writes slices now. One minor hitch here, as slicing for arrays has the upper bound not including and having the upper bound not including for proper ranges would be awkward. But then again I have more often tried using foo[$] to get the last element of an array and failed, then I have ever used foo[2..$] to get the last elements. Naturally the operator in should be able to work with ranges so that one could do for example: if (mychar in 'a'..'z') { ... } while (somenumber in 1..42) { ... }Very nice. Well thought out.And then sets: SetDeclaration: set [Identifier] SetBody SetBaseType: IntegerType SetBody: IntegerType EnumType RangeType { SetMembers } SetMembers SetMember [, SetMembers] SetMember: AssignExpression RangeMember SetType // To expand existing sets For example: set alfa {'A'..'Z', 'a'..'z'}; set alfanum { alfa, '0'-'9' }; enum weekday { MON, TUE, WED, THU, FRI, SAT, SUN }; set weekdays weekday; weekdays freedays = [TUE..THU, SAT]; if (selectedday in freedays) { ... } I mean how many of us have not written: if (tolower(ch) >= 'a' && tolower(ch) <= 'z' && ch >= '0' && ch <= '9') { ... } And even longer when writing for non English. This is much nicer: if (toupper(ch) in ['A'..'Z', '0'..'9']) { ... } And a compiler can optimize easy to just test bits.The only potential problem I can see in this is a conflict with static array literal syntax. Most notably your last line there: if (toupper(ch) in ['A'..'Z', '0'..'9']) { ... } You and I both know that you meant a set type for ['A'..'Z', '0'..'9'], but the compiler might think that ['A'..'Z', '0'..'9'] is a static array literal and will get confused on your use of ranges there. And then what would happen if your ['A'..'Z', '0'..'9'] looked like a real array literal with no ranges in it, but you meant it as a set? Silent bug. Something like ['I', 'V', 'X', 'C', 'L', 'M']? Is that a char[6] or a set? Hope that wasn't too obtuse. I do like your idea though!
Dec 07 2005
James Dunne skrev:Fredrik Olsson wrote:<snip>Ranges and sets :).The only potential problem I can see in this is a conflict with static array literal syntax. Most notably your last line there: if (toupper(ch) in ['A'..'Z', '0'..'9']) { ... } You and I both know that you meant a set type for ['A'..'Z', '0'..'9'], but the compiler might think that ['A'..'Z', '0'..'9'] is a static array literal and will get confused on your use of ranges there. And then what would happen if your ['A'..'Z', '0'..'9'] looked like a real array literal with no ranges in it, but you meant it as a set? Silent bug. Something like ['I', 'V', 'X', 'C', 'L', 'M']? Is that a char[6] or a set? Hope that wasn't too obtuse. I do like your idea though!Yes, it is a quite huge problem I guess as well. I remember reading in several places Walter stating that static arrays have been on for "v2.0", simply because of the problem of getting the type bottom up. I think the same problem applies here. And then using [] for both static arrays and static sets is a problem as well, as you say. Both for the programmer and definitely for the compiler. Unfortunately {} is already set aside for static structs, using () is not an option, and then we sort of ran out of parenthesis like character pairs :/. Perhaps <> can work. if (ch in <'a'..'z'>) { ... } Not too bad. But then again I think the syntax is the smallest obstacle :).
Dec 08 2005
Fredrik Olsson wrote:Ranges and sets :). For example: range minute 0..59; // Static range minute = 61; // Exception if compiling with range checks range slice: uint; // Dynamic range; int[12] foo; slice = 2..foo.length-2; int[] bar = foo[slice]; Range properties would be .min, .max, .length and naturally .sizeofI think there are TWO things going on here. (1) syntactic sugar for a built-in pair structure. struct range { int max; int min; }; This could be passed to opSlice. I don't see any need for it to be restricted to integral types; real numbers would make sense, too. Actually, this type would be almost identical to auto myrange = [1, 5]; except that the syntax is auto myrange = 1..5; (2) ability to apply a class invariant to a built-in type. This could be allowing a contracts to be applied to a typedef.range minute 0..59; // Static range minute = 61; // Exception if compiling with range checksis the same as something like: typedef int invariant { assert(this>=0 && this<=59); } Minute; // this assertion is checked every time there's // an assignment to a Minute variable. Minute minute; minute = 61; But you could also have more complex invariants, such typedef int invariant{ assert(this&1==0); } OddInt; to create an integer which must be odd. Except for the redefinition of 'this', it seems to be a natural extension of class invariants.
Dec 08 2005
In article <dn8vjc$17fo$1 digitaldaemon.com>, Don Clugston says.....(2) ability to apply a class invariant to a built-in type. This could be allowing a contracts to be applied to a typedef.Sweet! This would be great!range minute 0..59; // Static range minute = 61; // Exception if compiling with range checksis the same as something like: typedef int invariant { assert(this>=0 && this<=59); } Minute; // this assertion is checked every time there's // an assignment to a Minute variable. Minute minute; minute = 61; But you could also have more complex invariants, such typedef int invariant{ assert(this&1==0); } OddInt; to create an integer which must be odd. Except for the redefinition of 'this', it seems to be a natural extension of class invariants.
Dec 08 2005
Don Clugston wrote:Fredrik Olsson wrote:That invariant in the middle of the typedef declaration seems a bit out of place. What if typedefs had a body, where you could put many invariants, unittests (not sure about the usefulness of this one) and even methods! Like: enum weekday_enum { MON, TUE, WED, THU, FRI, SAT, SUN }; typedef weekday_enum weekday { invariant { assert(this >= MON && this <= SUN); } bool isWeekDay() { return (this >= MON && this <= FRI); } char[] toString() { ... // returns "Monday", "Tuesday", etc. } } ... weekday wday; wday = weekday.MON; writefln( wday.toString() ); -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."Ranges and sets :). For example: range minute 0..59; // Static range minute = 61; // Exception if compiling with range checks range slice: uint; // Dynamic range; int[12] foo; slice = 2..foo.length-2; int[] bar = foo[slice]; Range properties would be .min, .max, .length and naturally .sizeofI think there are TWO things going on here. (1) syntactic sugar for a built-in pair structure. struct range { int max; int min; }; This could be passed to opSlice. I don't see any need for it to be restricted to integral types; real numbers would make sense, too. Actually, this type would be almost identical to auto myrange = [1, 5]; except that the syntax is auto myrange = 1..5; (2) ability to apply a class invariant to a built-in type. This could be allowing a contracts to be applied to a typedef. > range minute 0..59; // Static range > minute = 61; // Exception if compiling with range checks is the same as something like: typedef int invariant { assert(this>=0 && this<=59); } Minute; // this assertion is checked every time there's // an assignment to a Minute variable. Minute minute; minute = 61; But you could also have more complex invariants, such typedef int invariant{ assert(this&1==0); } OddInt; to create an integer which must be odd. Except for the redefinition of 'this', it seems to be a natural extension of class invariants.
Dec 09 2005
Bruno Medeiros wrote:That invariant in the middle of the typedef declaration seems a bit out of place. What if typedefs had a body, where you could put many invariants, unittests (not sure about the usefulness of this one) and even methods! Like: enum weekday_enum { MON, TUE, WED, THU, FRI, SAT, SUN }; typedef weekday_enum weekday { invariant { assert(this >= MON && this <= SUN); } bool isWeekDay() { return (this >= MON && this <= FRI); } char[] toString() { ... // returns "Monday", "Tuesday", etc. } }And yes, the similarity to structs is something worth to note. Hum.. -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
Dec 09 2005
Bruno Medeiros wrote: And yes, the similarity to structs is something worth to note. Hum..Right, it's like a struct that inherits from a basic type, isn't it? struct weekday : weekday_enum { //... } or the same could be achieved by an anonimous member, or perhaps like with templates: member with the same name. struct weekday { weekday_enum weekday; } which would make a weekday implicitely castable to a weekday_enum? L.
Dec 12 2005
In article <dnc9qi$23js$1 digitaldaemon.com>, Bruno Medeiros says...<SNIP>That invariant in the middle of the typedef declaration seems a bit out of place. What if typedefs had a body, where you could put many invariants, unittests (not sure about the usefulness of this one) and even methods! Like: enum weekday_enum { MON, TUE, WED, THU, FRI, SAT, SUN }; typedef weekday_enum weekday { invariant { assert(this >= MON && this <= SUN); } bool isWeekDay() { return (this >= MON && this <= FRI); } char[] toString() { ... // returns "Monday", "Tuesday", etc. } } ... weekday wday; wday = weekday.MON; writefln( wday.toString() ); -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."I like the idea. It has my vote. For trivial types that need math ops it's lots better than structs.
Dec 09 2005
Fredrik Olsson wrote:Ranges and sets :). This is me more or less having a fantasy. Ranges and sets are without competition the two data types I use the most. They make writing solid code so much easy, helps finding range errors while debugging and reduces code size in general. Both fits quite nicely into existing functionality in D, as well as into the paradigm of making usable functionality part of the core language (as for complex numbers and strings). Ranges are semi there when slicing arrays, and sets can be emulates with associative arrays with somewhat awkward syntax. Anyway, if my x-mas wish comes true then :); RangeDeclaration: range [Identifier] [: RangeBaseType] [RangeBody] RangeBaseType: IntegerType RangeBody: RangeMember RangeMember: AssignExpression .. AssignExpression For example: range minute 0..59; // Static range minute = 61; // Exception if compiling with range checks range slice: uint; // Dynamic range; int[12] foo; slice = 2..foo.length-2; int[] bar = foo[slice]; Range properties would be .min, .max, .length and naturally .sizeof Constant ranges are written with the .. operator just as one writes slices now. One minor hitch here, as slicing for arrays has the upper bound not including and having the upper bound not including for proper ranges would be awkward. But then again I have more often tried using foo[$] to get the last element of an array and failed, then I have ever used foo[2..$] to get the last elements. Naturally the operator in should be able to work with ranges so that one could do for example: if (mychar in 'a'..'z') { ... } while (somenumber in 1..42) { ... } And then sets: SetDeclaration: set [Identifier] SetBody SetBaseType: IntegerType SetBody: IntegerType EnumType RangeType { SetMembers } SetMembers SetMember [, SetMembers] SetMember: AssignExpression RangeMember SetType // To expand existing sets For example: set alfa {'A'..'Z', 'a'..'z'}; set alfanum { alfa, '0'-'9' }; enum weekday { MON, TUE, WED, THU, FRI, SAT, SUN }; set weekdays weekday; weekdays freedays = [TUE..THU, SAT]; if (selectedday in freedays) { ... } I mean how many of us have not written: if (tolower(ch) >= 'a' && tolower(ch) <= 'z' && ch >= '0' && ch <= '9') { ... } And even longer when writing for non English. This is much nicer: if (toupper(ch) in ['A'..'Z', '0'..'9']) { ... } And a compiler can optimize easy to just test bits.Do you mean you miss them from Pascal? Your examples match Pascal pretty closely: type Weekday = ( MON, TUE, WED, THU, FRI, SAT, SUN ); WeekdaySet = Set of Weekday; Charset = Set of Char; DayOfWeek : 1..7 ; var weekdays : WeekdaySet; characters : Charset; This is no slight on you, but its amusing to see programmers wish for features available on a language developed in 1970.. hee hee. (A Pascal fan) -DavidM
Dec 09 2005
David Medlock skrev:Fredrik Olsson wrote:<snip>Ranges and sets :).This is no slight on you, but its amusing to see programmers wish for features available on a language developed in 1970.. hee hee. (A Pascal fan) -DavidMNo coincident at all :). I am a Pascal fan as well, and Lisp fan, and Ruby fan and sql fan, and etc. I am simply choose what I feel is the best tool for the task at hand. For the general case Pascal tended to be it, before I found D. So naturally I want D to fill the few gaps I miss //Fredrik
Dec 09 2005
Fredrik Olsson wrote:David Medlock skrev:You actually /LIKE/ SQL? http://orlyowl.com/omg.jpgFredrik Olsson wrote:<snip>Ranges and sets :).This is no slight on you, but its amusing to see programmers wish for features available on a language developed in 1970.. hee hee. (A Pascal fan) -DavidMNo coincident at all :). I am a Pascal fan as well, and Lisp fan, and Ruby fan and sql fan, and etc. I am simply choose what I feel is the best tool for the task at hand. For the general case Pascal tended to be it, before I found D. So naturally I want D to fill the few gaps I miss //Fredrik
Dec 09 2005
James Dunne wrote:Fredrik Olsson wrote:SQL is reasonably laid out, and can be readily optimized since it is a declarative language, but its predecessor I like quite a lot more: http://en.wikipedia.org/wiki/IBM_BS12 -DavidMDavid Medlock skrev:You actually /LIKE/ SQL? http://orlyowl.com/omg.jpgFredrik Olsson wrote:<snip>Ranges and sets :).This is no slight on you, but its amusing to see programmers wish for features available on a language developed in 1970.. hee hee. (A Pascal fan) -DavidMNo coincident at all :). I am a Pascal fan as well, and Lisp fan, and Ruby fan and sql fan, and etc. I am simply choose what I feel is the best tool for the task at hand. For the general case Pascal tended to be it, before I found D. So naturally I want D to fill the few gaps I //Fredrik
Dec 09 2005
David Medlock skrev:James Dunne wrote:<snip>Fredrik Olsson wrote:David Medlock skrev:Fredrik Olsson wrote:Ranges and sets :).SQL appeals to me because of it's small set of functionally that allows for so much to be done. I can not help it, but sometimes I chuckle for minutes after completing a particularly ingenious query :). Combine with pl/SQL or PostgreSQL's pl/pgSQL and you pretty much have what you need. My company's current project is pretty much an server written in "PostgreSQL" with a dummy web GUI in PHP. // FredrikSQL is reasonably laid out, and can be readily optimized since it is a declarative language, but its predecessor I like quite a lot more: http://en.wikipedia.org/wiki/IBM_BS12You actually /LIKE/ SQL? http://orlyowl.com/omg.jpg
Dec 14 2005
In article <dn6re3$ckq$1 digitaldaemon.com>, Fredrik Olsson says...Ranges and sets :). This is me more or less having a fantasy. Ranges and sets are without competition the two data types I use the most...I find ranges and sets and tuples and other such Lispy datatypes extremely useful, too. Many popular recent languages include them and I'd like to see them in D to the extent possible.For example: range minute 0..59; // Static range minute = 61; // Exception if compiling with range checks range slice: uint; // Dynamic range; int[12] foo; slice = 2..foo.length-2; int[] bar = foo[slice];Naturally the operator in should be able to work with ranges so that one could do for example: if (mychar in 'a'..'z') { ... } while (somenumber in 1..42) { ... }And let's not forget: for (int i: 0..9) { ... } I think that's a lot nicer than: for (int i=0; i<9; i++) { ... } and the compiler could easily generate the same code for both.And then sets:For example: set alfa {'A'..'Z', 'a'..'z'}; set alfanum { alfa, '0'-'9' }; enum weekday { MON, TUE, WED, THU, FRI, SAT, SUN }; set weekdays weekday; weekdays freedays = [TUE..THU, SAT]; if (selectedday in freedays) { ... } I mean how many of us have not written: if (tolower(ch) >= 'a' && tolower(ch) <= 'z' && ch >= '0' && ch <= '9') { ... } And even longer when writing for non English. This is much nicer: if (toupper(ch) in ['A'..'Z', '0'..'9']) { ... } And a compiler can optimize easy to just test bits.and again, something like: for ( Day day : [MON..THU, SAT] ) { ... } Python ran into some trouble with the concept of ranges because it was calculating all of the members first before using any of them. It then added the "xrange" feature, which is related to "generators" or "continuations". Each element in an xrange is calculated on a just-in-time basis rather than all up front. You can then use infinite sets (such as all prime numbers) the same way you use small finite sets. You could then have something roughly like: int generator primes = primeGenerator(); for (int i : primes) { ... } primeGenerator would be a "generator" function that acted like a set of int's but would stay active on the stack between calls generating successive values (not "returning" values and leaving the stack between calls like a regular function, but staying loaded and "yielding" the next value each time it was called). After writing the generator function "primeGenerator()", the programmer could then simply think of "primes" as the set of all prime numbers and use it like any other set.
Dec 10 2005