Nullable or Optional? Or something else?

Daniel Keep daniel.keep.lists at gmail.com
Tue Sep 8 19:51:04 PDT 2009


Andrei Alexandrescu wrote:
> I plan to add a Nullable struct to Phobos (akin to C#'s Nullable,
> Boost's Optional).
> 
> Apparently a good design is to define Optional!T with a minimum of
> member functions (ideally none) and have it use the "alias this" feature
> to masquerade as a T. That way Optional!T looks and feels much like a T,
> except that it supports a function
> 
> bool isNull(T)(Optional!T value);
> 
> Am I on the right track? If so, what is the name you'd prefer for this
> artifact?
> 
> 
> Andrei

Given the apocalyptic battle raging in this thread at the moment, maybe
it would be pertinent to have both.  Sometimes, you do want a generic
mechanism for representing "this may or may not have a value".  Other
times, you just want something with a "no value set" sentinel.

Nullable!T would be a type for which 'null' is a valid value.  By this
definition, Nullable!(Nullable!T) is obviously equivalent to Nullable!T;
it's equivalent to T if T is either a pointer, array or object.

Optional!T would be a type where an instance may or may not have a value
of type T; even if T is itself Optional.

I'm tempted to put an alias this into Optional and just define an
external contentsOf function that pulls out the value contained in the
Optional.  Not sure if that's the right choice or not.

So that gives us:

struct Nullable(T)
{
    private
    {
        T __value;
        bool __isNull;
        T __get_value()
        {
            if( __isNull ) throw new Exception;
            return __value;
        }
    }
    alias __get_value this;
}
struct Optional(T)
{
    private
    {
        T __value;
        bool __isNull;
        T __get_value()
        {
            if( __isNull ) throw new Exception;
            return __value;
        }
    }
    // Maybe: alias __get_value this;
    alias __get_value opCall;
    bool isNull()
    {
        return __isNull;
    }
}

static assert( is( Nullable!(Nullable!int) == Nullable!int ) );

bool isNull(T)(T v) if (isNullable!T)
{
    return v.__isNull;
}

bool isNull(T)(T v) if (isOptional!T)
{
    return v.isNull;
}

/+ Maybe:
T contentsOf(T)(T v) if (isNullable!T || isOptional!T)
{
    return v.__get_value;
}
+/



More information about the Digitalmars-d mailing list