On 2013-10-10, 13:28, monarch_dodra wrote:

On Thursday, 10 October 2013 at 10:09:23 UTC, Andrei Alexandrescu
wrote:
I'm confused. I thought Nullable!T == T is well defined to mean "true" if a value is present and equal to the right-hand side, or "false" otherwise (the absence of a value is a singularity unequal with all objects). What's harmful about that?

Andrei

That in itself, I think is actually OK. It would be OK, because I
think we can agree that a "no-value" is different from any value.
In this case, we are making a call to Nullable's opEqual. I'm
actually fine with this, because it is a call to Nullable's
member function.

The point though is that this crashed at runtime, and nobody
until now noticed it, because of the "alias this". Ditto for
toString. Ditto for to hash.

My argument is against the "alias this" itself. It is making a
cast when we don't actually expect it. Basically, any time you do
a call on said nullable, you have to really think about what you
are doing, because your nullable *will* be referenced on the
first chance it gets.

Basically, passing a Nullable!T to any function that expects a T
is a silent runtime danger, which we really shouldn't have to
accept.

Hear hear! I've just played around with implementing a tagged
union myself, and opted for explicit everywhere[0], with this being
the preferred method for accessing the stored value:

  TaggedUnion!(string, float, int, Tuple!(long, long)) a;

  a.match!(
    (string s) => writeln("It's a string!"),
    (float f)  => writeln("It's a float!"),
    (Else)     => writeln("It's something else!"),
  );

This way, I'm always forced to handle the other cases.
This work also gave me a free Nullable:

  alias NullableT(T) = TaggedUnion!(T, typeof(null));

I admit I have not tested the latter, so it might in fact not work
very well. :p

Also, opEquals proved troublesome to implement, as typeof(null)
is not comparable to typeof(null). Oh, and for such a generic type,
should TaggedUnion!(int, string) be comparable to
TaggedUnion(int, float)?


[0]: If I want to play unsafe, I can also access the stored value
like so:

float f = a.as!float;

--
  Simen

Reply via email to