Current sentiment on Nullable.get

aliak something at something.com
Fri Dec 14 21:47:26 UTC 2018


On Thursday, 13 December 2018 at 13:47:34 UTC, Jonathan M Davis 
wrote:
> Which you can do with a pointer. There is no need to have an 
> "optional" type if you don't care about heap allocations. If 
> you don't care about heap allocations, than you can just use T* 
> and not bother with creating a library type. It even works if 
> you already have a pointer, because you can have a pointer to a 
> pointer: T**. Having an optional/maybe type allows you to 
> indicate whether a value is present _without_ that extra heap 
> allocation. It gives you pointer semantics with regards to 
> whether a value is present without needing a pointer. So, 
> ultimately, avoiding a heap allocation is the reason that such 
> optional/maybe types exist, and it's why Nullable exists.

Maybe it's why Nullable in D exists for *some* types, but it is 
certainly not why optional types exist -> 
https://en.wikipedia.org/wiki/Option_type.

Why would you use Nullable!Class, or Nullable!(T*)? It's not to 
avoid allocation.

Now whether or not you think a pointer is good enough is a 
different argument. If you are in the camp where a pointer is 
good enough then that's fine but I completely disagree with a 
pointer being good enough to represent the absence of a value. 
That's a hack with pointers. Just like you can use functions to 
model object oriented programming, it's a hack. In the case of 
pointers it only works if you consider null as not being part of 
a pointer's value domain. If you think null is a valid value of a 
pointer, then you're stuck.

Also, "if (!null) then do something" is becoming more recognized 
as an anti pattern these days, and having pointers represent 
existence just helps you litter your code with null checks. 
Checking for null becomes an unenforcible requirement for 
stability. Instead, with a properly designed optional type, this 
requirement becomes checked and/or forced.

> The behavior is completely obvious if you understand that 
> whether a Nullable is null refers to the Nullable itself and 
> not the value that it contains. Looking at the documentation, 
> it does need to be improved so that that is clearer. But if you 
> understand that, then there is no confusion.

The behavior of many things becomes completely obvious once you 
understand a set of things, generally speaking. The brain power 
needed to understand that is unnecessarily more than what would 
be required with a better/different API.

>
> And if you're not writing generic code, then the only reason to 
> even put a pointer or reference in a Nullable in the first 
> place is so that you can differentiate between a pointer or 
> reference that has been given a value rather than being simply 
> default-initialized. If you didn't care about that, then you 
> would just use the pointer or reference directly, because the 
> Nullable would do _nothing_ for you. It would be a pointless 
> wrapper.

The Nullable implementation does indeed make it a pointless 
wrapper. Which is the problem. It actually make it worse. Because 
with a pointer or reference, if you check is null, then you know 
you can use it, but with Nullable, checking isNull doesn't give 
you any guaranteers.

>
> And if you're writing generic code, then having isNull act 
> differently for pointers than it does for value types would not 
> work at all, because you'd have to special-case the code to 
> handle the fact that assigning the Nullable a value could still 
> result in isNull being true in the case where the Nullable 
> contained a pointer or reference. So, the code would no longer 
> be generic. And if it wasn't going to be generic, then you'd

Why would you want to use a pointer or reference that is null?

Right now you have to do this:

void f(T)(Nullable!T a) {
   if (!a.isNull) {
     static if (is(T == class) || isPointer!T || is(T == 
interface)) {
       if (a.get !is null) {
         // can use a
       }
     } else {
       // can you a
     }
   }
}


> just use the naked pointer or reference rather than using a 
> Nullable. The entire reason that Nullable was changed to allow 
> types that are naturally nullable was so that generic code 
> could use Nullable without having to be special-cased for 
> pointers or references. That does come with the downside that 
> isNull might be confusing if you don't understand what Nullable 
> is, and the documentation clearly needs to be improved on that 
> front, but there's no problem there with how Nullable works. 
> It's just now a worse name, because it was changed to allow 
> types that are naturally nullable and that can therefore have 
> the value of null.
>
>> > IMHO, the only real naming issue that we have with Nullable 
>> > is that once it was changed to allow actual pointers 
>> > (whereas originally, it just contained types that could not 
>> > themselves be null), the property isNull became confusing to 
>> > some folks, because they thought that the null value of a 
>> > pointer and whether the Nullable itself was null were 
>> > related, when they're not (and if they were, it would cause 
>> > subtle bugs - especially in generic code).
>>
>> Yes, and this is just bad. Bad bad bad. How can any API that 
>> causes subtle bugs be something anyone would want to keep 
>> around??
>
> How on earth does Nullable cause subtle bugs?

Au. I misread your sentence as saying Nullable causes subtle bugs 
:o Sorry.

Cheers,
- Ali


More information about the Digitalmars-d mailing list