Nullable or Optional? Or something else?
Steven Schveighoffer
schveiguy at yahoo.com
Tue Sep 8 13:41:26 PDT 2009
On Tue, 08 Sep 2009 15:50:15 -0400, Rainer Deyke <rainerd at eldwood.com>
wrote:
> Steven Schveighoffer wrote:
>> 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.
>
> Yes, in this particular case, passing a default value would work just as
> well. But what if you want to cache the contents of the entire
> configuration file? What if calculating the default value is an
> expensive operation that should be avoided if possible?
You're reaching here :) A default configuration value that is expensive
to calculate?
> My argument isn't about any specific example. My argument is that
> inconsistent behavior in corner cases is the bane of good programming.
I understand what you are saying, but often times (as I have learned from
my own crusades on the NG), when it is hard to find good cases for an
argument, it means the argument is superficial or academic. I could very
well be wrong, but to me, the practicality of the offered use cases is
important when evaluating whether to complicate syntax.
It's like saying that all integers should be arbitrary precision, because
sometimes you need arbitrary precision integers. The better answer is
BigInt. If you need arbitrary precision, use that, otherwise int is good
enough for most cases.
>> 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.
>
> I thought the whole point of the Optional library type was to remove the
> need for user-defined types consisting of a boolean and a T, where the T
> is only valid if the boolean is 'true'? If the real answer is to write
> a new, different type, why have Optional at all?
I thought it was to provide a way to make a value type have an "unset"
value. There is no reason in my opinion to make *all* uses of the new
type be able to represent multiple values for "unset". If that is what
you want, then I think it can be done, but it should not affect the syntax
for the majority of cases.
>>> 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.
>
> You can't have that, because 'v' is already the container. The best you
> can get is a proxy that sometimes acts like a containee, but really
> isn't. This kind of sloppy thinking has no place in computer
> programming.
You mean like struct pointers? Generic type wrappers? Remote object
proxies? :P
Really, what I think we want to do is add a new operation to a type -- "is
null". Not two operations, "is null" and "get containee".
-Steve
More information about the Digitalmars-d
mailing list