Improvements to std.typecons.Nullable

Simen Kjaeraas simen.kjaras at gmail.com
Thu Oct 10 15:40:10 PDT 2013


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


More information about the Digitalmars-d mailing list