Nullable or Optional? Or something else?

Steven Schveighoffer schveiguy at yahoo.com
Tue Sep 8 04:49:20 PDT 2009


On Fri, 04 Sep 2009 22:45:40 -0400, Rainer Deyke <rainerd at eldwood.com>  
wrote:

> Steven Schveighoffer wrote:
>> I disagree, how many ways do you want to say something is unset?  I
>> think one case -- is this thing null -- is plenty for 99% of cases.
>> Your case, well, I had trouble understanding it, but I think the nuance
>> of how something is unset is not usually important.
>
> Possible use case for Optional: storing an upper limit.  In this case
> "null" means "there is no upper limit".
>
> Possible use case for Optional: a function that retrieves a value from a
> configuration file.  In this case, "null" means "the value is not found
> in the configuration file".
>
> So what happens if you want to store that there is no upper limit in a
> configuration file?
>

Why do you care if it was or was not found in the configuration file  
beyond the call to retrieve it?  Pass in a default value (of null if you  
wish), or have the function return a separate boolean indicating whether  
it was found or not.  Using a new type just to determine if something was  
found during a function call seems like a waste to me.  If there's a  
reason to store that fact beyond the function call, then create a new type  
which stores that fact.  You shouldn't complicate the syntax for the sake  
of a corner case.

What do you think is more confusing?

auto val = getConfig("upperlimit")
if(val is null)
   upperLimit = default_upper_limit;
else
   upperLimit = *val;

- or -

upperLimit = getConfig("upperlimit", default_upper_limit);

>> I think that what you will find with a solution that *does* allow this,
>> you will be sacrificing something else -- such as syntax clarity or a
>> member function.
>
> No, keeping the container and the containee separate leads to /clearer/
> (if slightly more verbose) syntax.  My proposal is to use use pointer
> syntax:
>   Optional!T v;
>   f(v); // Do something with the container.
>   f(*v); // Do something with the containee.

Hm... that means you have to use *v every time you want the value, and  
just v if you want to check for null?  I think the most common case is  
using the containee, I'd rather have that be the default.

-Steve



More information about the Digitalmars-d mailing list