April 04, 2014 Re: Interesting rant about Scala's issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Friday, 4 April 2014 at 18:15:43 UTC, Meta wrote: >> And another: >> >> array[A + 1] = t; // Error: incompatible types Index and int >> >> And another: >> >> enum Mask { A=1,B=4 } >> >> Mask m = A | B; // Error: incompatible operator | for enum >> >> and on it goes. These are routine and normal uses of enums. https://github.com/D-Programming-Language/phobos/pull/2058 Perhaps we *will* get typesafe enums of a sort via a library implementation. |
April 04, 2014 Re: Interesting rant about Scala's issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright: Thank you for the answers. > Here's one: > > enum Index { A, B, C } > T[Index.max] array; // Error: Index.max is not an int > ... > array[B] = t; // Error: B is not an int In the last months I've grown a moderate desire for optionally strongly typed array indexes in D (as seen in Ada, but with a different syntax) (it's optional, so it's meant to be an additive change, that causes no harm to existing D code). With them code like yours becomes OK (as it's OK in Ada). Such optional strong typing for array indexes is not means for script-like D programs, but for the medium-integrity D programs. > And another: > > array[A + 1] = t; // Error: incompatible types Index and int This can be solved with optionally strongly typed array indexes plus a succ/prec property for enums. I have asked for such property years ago. In Ada you use the built in function "Succ". Alternatively, in D you can also use a library-defined group of little functions/templates succ/prec/Succ/Prec (that contain a cast, but it's in Phobos, so it's less dangerous than a cast in user code): array[Succ!(Index.A)] = t; auto i = Index.A; array[i.succ] = t; > And another: > > enum Mask { A=1,B=4 } > > Mask m = A | B; // Error: incompatible operator | for enum In GitHub there is a patch that is meant to implement Flags in library code (in C# such Flags are almost first-class, using [Flags]): https://github.com/D-Programming-Language/phobos/pull/2058 If such Flags is implemented with enums, then it contains casts, but again casts in Phobos are less dangerous than casts in user code. Bye, bearophile |
April 04, 2014 Re: Interesting rant about Scala's issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | Meta: > Also, if I remember correctly, min and max are terribly > broken for enums in the first place. Yes, perhaps they need to be deprecated. Also, there is a ugly name clashing between enum field names and the enum properties. The solution is to group them into a single namespace (like "meta"), and then forbid an enum member with the name of the namespace. https://d.puremagic.com/issues/show_bug.cgi?id=4997 Unfortunately overall the design of D enums has more holes than swiss cheese. This is why in a recent post I said to Andrei that perhaps there are still several little breaking changes to do to D, and they need priority over additive enhancements. Bye, bearophile |
April 04, 2014 Re: Interesting rant about Scala's issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | >> And another:
>>
>> enum Mask { A=1,B=4 }
>>
>> Mask m = A | B; // Error: incompatible operator | for enum
That would be a 'set of enum' in Pascal/Delphi.
|
April 04, 2014 Re: Interesting rant about Scala's issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Fri, Apr 04, 2014 at 11:02:01 -0700, Walter Bright wrote: > Most of the casts in Warp come from the workarounds I had to do to get around the auto-decode of std.array.front(). I have designed byChar, byWchar and byDchar ranges for Phobos to get around this issue, but that is stalled now because of the messed up design of ranges. Sorry, I'm a D noob; what's 'auto-decode'? > Here's one: > > enum Index { A, B, C } > T[Index.max] array; // Error: Index.max is not an int > ... > array[B] = t; // Error: B is not an int Maybe instead of having array indices be int, having them specify some interface (akin to Ix[1] used by Haskell's Array). Not that this is likely fixable at this point. > And another: > > array[A + 1] = t; // Error: incompatible types Index and int > > And another: > > enum Mask { A=1,B=4 } > > Mask m = A | B; // Error: incompatible operator | for enum I like Qt's Q_FLAG and Q_FLAGS where you have a separate type for the flags and combined flags. Maybe something like: enum MaskBits { mixin EnumBits!MaskBits; A=1, B=4 } alias Flags!MaskBits Mask; where EnumBits would define the binary operations would be possible? > And besides, even if such strongly typed enums were a good idea, making such a change would be an utter disaster for existing code. It is out of the question. Agreed. There's also Haskell's 'newtype' which might be useful to have (strongalias? strictalias?). I guess this is no different than something like: class NewType(T) { private: T store; public this(T store) { this.store = store; } package T unT() { return store; } } and if you want unT to be public: public T unT(NewType!T nt) { return nt.unT(); } --Ben [1]http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Ix.html |
April 04, 2014 Re: Interesting rant about Scala's issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > array[Succ!(Index.A)] = t;
> auto i = Index.A;
> array[i.succ] = t;
And with "enum precondition" in the succ() function you can do both cases with a single function:
array[Index.A.succ] = t;
auto i = Index.A;
array[i.succ] = t;
Bye,
bearophile
|
April 04, 2014 Re: Interesting rant about Scala's issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 4/4/2014 11:47 AM, bearophile wrote: > Also, there is a ugly name clashing between enum field names and the enum > properties. The solution is to group them into a single namespace (like "meta"), > and then forbid an enum member with the name of the namespace. > > https://d.puremagic.com/issues/show_bug.cgi?id=4997 Actually, that was intentional, which is why the issue is marked as "enhancement". The builtin properties are override-able. > Unfortunately overall the design of D enums has more holes than swiss cheese. Enums are not meant to be rigidly typed. > This is why in a recent post I said to Andrei that perhaps there are still > several little breaking changes to do to D, and they need priority over additive > enhancements. I understand your concerns, but I don't share your opinion that they need fixing. Their behaviors were deliberately designed, and in my experience work out nicely. |
April 04, 2014 Re: Interesting rant about Scala's issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 4/4/2014 12:05 PM, bearophile wrote: > And with "enum precondition" in the succ() function you can do both cases with a > single function: > > array[Index.A.succ] = t; > auto i = Index.A; > array[i.succ] = t; What about i+10? Do you expect the person to write i.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ? Sorry, that sux! And what about: int j; array[i+j] ? And forcing the user to use templates to do any logical or arithmetic operations on enum operands? It's just awful. |
April 04, 2014 Re: Interesting rant about Scala's issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Boeckel | On Friday, 4 April 2014 at 18:57:44 UTC, Ben Boeckel wrote:
> On Fri, Apr 04, 2014 at 11:02:01 -0700, Walter Bright wrote:
>> Most of the casts in Warp come from the workarounds I had to do to
>> get around the auto-decode of std.array.front(). I have designed
>> byChar, byWchar and byDchar ranges for Phobos to get around this
>> issue, but that is stalled now because of the messed up design of
>> ranges.
>
> Sorry, I'm a D noob; what's 'auto-decode'?
unicode decoding. front decodes a code-point from a string instead of a code-unit (single char)
|
April 04, 2014 Re: Interesting rant about Scala's issues | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Fri, Apr 04, 2014 at 13:04:28 -0700, Walter Bright wrote: > On 4/4/2014 12:05 PM, bearophile wrote: > >And with "enum precondition" in the succ() function you can do both cases with a > >single function: > > > >array[Index.A.succ] = t; > >auto i = Index.A; > >array[i.succ] = t; > > What about i+10? Do you expect the person to write i.succ.succ.succ.succ.succ.succ.succ.succ.succ.succ? Sorry, that sux! You say that, I see a pattern: Presumably, you'd have something like: iter :: Int -> (a -> a) -> a -> a so you'd have: array[iter(j, succ, i)] But really, I think using an interface (cf Ix referenced elsewhere in the thread) rather than a concrete type for array indices may have been better, but I also think that ship has sailed here. > And what about: > > int j; > array[i+j] Why would you be adding arbitrary integers to enumerations and expecting a valid result? > And forcing the user to use templates to do any logical or arithmetic operations on enum operands? It's just awful. Again, interfaces :) . --Ben |
Copyright © 1999-2021 by the D Language Foundation