April 09, 2014
On 4/8/14, 3:06 PM, H. S. Teoh wrote:
> On Tue, Apr 08, 2014 at 09:46:51PM +0000, Meta wrote:
>> On Tuesday, 8 April 2014 at 19:09:55 UTC, Andrei Alexandrescu wrote:
> [...]
>>> 3. What is the priority of improving enums in the larger picture of
>>> other things we must do?
>>
>> Enums could stand to be improved, but finishing the implementation of
>> the language should take precedent.
>
> Yes! There are much bigger fish to fry than enums right now. Let's not
> lose sight of the forest for the trees.

I'm glad to see this trend! :o)

There are a couple of simple functions we can add to improve the enum experience incrementally (E is an enumerated type):

E succ(E value);
E succ(E value, E overflow) nothrow;
E pred(E value);
E pred(E value, E overflow) nothrow;

They'd return the successor/predecessor of value in the enumerated type, assuming it's ordered and has increment. Probably should only work for integral enums. It would prefer real ordering to lexical ordering, or would refuse to work with enums that are inconsistent.


Andrei

April 09, 2014
On Wednesday, 9 April 2014 at 16:47:18 UTC, Andrei Alexandrescu wrote:
> Very true. In hhvm, we tried an enum class to avoid bugs with using wrong indices in a couple of specific arrays. There were so many darned casts around, we had to revert the change.


There are many ways to get around this, such as user-defined function or template, or a built-in .valueOf property.

template ValueOf(alias E)
if (is(typeof(E) == enum))
{
	import std.traits: OriginalType;
	
	enum OriginalType!(typeof(E)) ValueOf = E;
}

You can call this in a function for use with UFCS.

April 09, 2014
On 4/9/14, 10:17 AM, Meta wrote:
> On Wednesday, 9 April 2014 at 16:47:18 UTC, Andrei Alexandrescu wrote:
>> Very true. In hhvm, we tried an enum class to avoid bugs with using
>> wrong indices in a couple of specific arrays. There were so many
>> darned casts around, we had to revert the change.
>
>
> There are many ways to get around this, such as user-defined function or
> template, or a built-in .valueOf property.
>
> template ValueOf(alias E)
> if (is(typeof(E) == enum))
> {
>      import std.traits: OriginalType;
>
>      enum OriginalType!(typeof(E)) ValueOf = E;
> }
>
> You can call this in a function for use with UFCS.

That was for C++, and a function vs. a cast didn't improve the experience much. -- Andrei

April 09, 2014
On Wednesday, April 09, 2014 08:38:54 Andrei Alexandrescu wrote:
> Too restrictive. What is a valid enum value? Would an enum flags need to ascribe a name to every possible combination?

Why is that too restrictive? I don't see how it even fundamentally makes sense for

    auto result = MyEnum.a | MyEnum.b;

to result in a value of type MyEnum. It _might_ result in a valid enum value, but if an enum is supposed to represent a specific set of flags or constants, in the general case, I would expect that doing any arithmetic operation on them (or concatenating to them in the case of something like strings) would result in a value that was not a valid enum value, and I don't see how anyone could really expect that code like

    MyEnum result = MyEnum.a | MyEnum.c;
    StringEnum str = SringEnum.s ~ " foo";

could be considered valid except in rare cases, and in those cases, you could
simply cast the result to the enum type since you know that it's going to
result in a valid enum value. I fail to see why you'd even _want_ the result
of operations on an enum to result in the same type given that it's almost
a guarantee that it won't result in one of the enumerated values.

- Jonathan M Davis
April 09, 2014
On Wednesday, 9 April 2014 at 18:05:15 UTC, Andrei Alexandrescu wrote:
> That was for C++, and a function vs. a cast didn't improve the experience much. -- Andrei

The difference being that a function is safe whereas a cast is not.
April 09, 2014
On Wednesday, 9 April 2014 at 18:18:57 UTC, Meta wrote:
> On Wednesday, 9 April 2014 at 18:05:15 UTC, Andrei Alexandrescu wrote:
>> That was for C++, and a function vs. a cast didn't improve the experience much. -- Andrei
>
> The difference being that a function is safe whereas a cast is not.

When going the other way, that is. When going from enum -> value, E.val is more sightly than cast(int)E.
April 09, 2014
On 4/9/14, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> E succ(E value);
> E succ(E value, E overflow) nothrow;
> E pred(E value);
> E pred(E value, E overflow) nothrow;

Not to nitpick, but next/prev for the names is easier to understand. "succ" is rare, and "pred" reminds me of "predicate".
April 09, 2014
On 03/04/2014 02:55, Andrei Alexandrescu wrote:
> A lot of them could apply to us as well.
>
> https://www.youtube.com/watch?v=TS1lpKBMkgg
>
>
> Andrei

One interesting point near the end. He glossed over it since he was running out of time, but this was in the slides:

"
What I'm after
* I don't need a programming language.
* I need a coherent set of tools for creating software. A "language" is incidental.
"

I totally agree. Sure, the language may be the core, and one of the most important aspects, but the rest of the tool-chain is extremely important too.

I don't think everyone in the D community (and outside it too) fully stands behind this idea.

-- 
Bruno Medeiros
https://twitter.com/brunodomedeiros
April 09, 2014
On 4/9/2014 4:21 PM, Bruno Medeiros wrote:
>
> Sure, the language may be the core, and one of the most
> important aspects, but the rest of the tool-chain is extremely important
> too.
>
> I don't think everyone in the D community (and outside it too) fully
> stands behind this idea.
>

I think a big part of that is because there's been a lot of work done using languages where good tooling is used as a substitute for a good language (*cough*java*cough*) - to predictably painful results.

Tooling is certainly very important, but until someone comes up with a substitute for "programming languages" that actually *works well* as a *complete* substitute (decades of attempts, still zero successes), then unlike tooling, the language is still the one thing that's absolutely *mandatory*.

April 09, 2014
On 4/9/14, 11:14 AM, Jonathan M Davis wrote:
> On Wednesday, April 09, 2014 08:38:54 Andrei Alexandrescu wrote:
>> Too restrictive. What is a valid enum value? Would an enum flags need to
>> ascribe a name to every possible combination?
>
> Why is that too restrictive? I don't see how it even fundamentally makes sense
> for
>
>      auto result = MyEnum.a | MyEnum.b;
>
> to result in a value of type MyEnum.

One wants to call a function taking such an enum. -- Andrei