Nullable or Optional? Or something else?

Steven Schveighoffer schveiguy at yahoo.com
Fri Sep 11 03:56:16 PDT 2009


On Fri, 11 Sep 2009 00:49:58 -0400, Rainer Deyke <rainerd at eldwood.com>  
wrote:

>> Do they?
>
> They absolutely do.  You pass in an 'int', you get one result, you pass
> in an 'Optional!int', you get another result.
>
> Maybe the use of exceptions is confusing you.  Here is another example:
>
>   void defaultInitialize(T)(ref T) {
>     T = T.init;
>   }
>
> Again, one result if you pass in an 'int', another result if you pass in
> an 'Optional!T'.  Logically the same operation, but physically different
> results.

Just like defaultInitialize(double_value) is different than  
defaultInitialize(int_value).  So what?  I still don't get the problem.   
Optional!int is not an int.  I never said it was.

>> report_error(typeof(v).init);
>
> That's another good example, actually.
>
>   report_error(typeof(v).init);
>
> Legal when 'typeof(v)' is an int.  Illegal if 'typeof(v) is
> 'Optional!int', because 'Optional!int' is not and cannot be fully
> equivalent to 'int' while also supporting null functionality.

You didn't give me any details on report_error.  If report_error takes an  
int, then yes, it fails at runtime, but that line of code is broken  
anyways.  Why should report_error take ANY arguments when you always pass  
it an uninteresting value?  If you always want to report the same thing,  
then use an int literal.

Why do you think Optional!int has to act EXACTLY like an int?  If it did  
THERE WOULD BE NO POINT!

> When you just see that one line of code, the problem is obvious.  When
> it's buried in several layers of template code, then it's a lot less
> obvious.

Welcome to the world of programming, where logic errors are not obvious,  
I'm sorry the compiler can't flag all your errors for you.  BTW, this  
example would behave no differently with your proposal.  Amazingly even  
this compiles!

int *ptr;
report_error(*ptr);

>> They can act like the base type up to a point.  You make it sound like a
>> chore to use a wrapper type, but the truth is they are easy to use,
>> there are not that many cases to worry about.
>
> Up until you forget about one of those cases, at which you have a
> program that mysteriously fails to compile at best and an incorrect
> program at worst.

If you cannot deal with the cases where it's different, then don't use  
it.  Use a struct with a boolean where the accesses to the object and the  
boolean are spelled out for you if you need that kind of assurance.  It's  
not that interesting of a type, it doesn't belong in the standard library  
(well, maybe as the generic pair!(T, U) ).

-Steve



More information about the Digitalmars-d mailing list