Current sentiment on Nullable.get

Rubn where at is.this
Sat Dec 15 00:05:51 UTC 2018


On Friday, 14 December 2018 at 23:08:30 UTC, Jonathan M Davis 
wrote:
> On Friday, December 14, 2018 3:23:57 PM MST Rubn via 
> Digitalmars-d wrote:
>> On Thursday, 13 December 2018 at 13:47:34 UTC, Jonathan M Davis
>>
>> wrote:
>> > 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.
>>
>> Isn't the behavior of everything obvious if you know how it 
>> works? The reasons things should be named the way they are is 
>> to help identify what they do. What you are describing is more 
>> easily understood as a class named "Optional".
>>
>> You mention that the template didn't work with types that were 
>> already nullable. I want to know what the individual was 
>> thinking when they expanded the functionality to include 
>> nullable types. They could have easily added extra code that 
>> does an additional check to see if the types are null. That's 
>> the logical thing to do for a class named "Nullable". The way 
>> it is currently implemented is the logical way to implement 
>> "Optional". You wouldn't store a float point number in a type 
>> called int, would you ?
>
> As I already explained in multiple posts here, the entire 
> reason that Nullable was expanded to work with pointers and 
> classes was so that it would work in generic code. So, it's now 
> possible to have a templated function or type use Nullable 
> without caring about what type it actually contains. It's just 
> whatever type the template was instantiated with, whereas 
> previously it would have had to do stuff like
>
> static if(is(Nullable!T))
>     n.nullify()
> else
>     n = null;
>
> and
>
> static if(is(Nullable!T))
>     return n.get;
> else
>     return *n;
>
> in order to work with both naturally nullable types and those 
> that need Nullable to be "null" in a single piece of templated 
> code. Now, you can just do
>
> n.nullify();
>
> and
>
> return n.get;
>
> regardless of whether the Nullable contains a naturally 
> nullable type or not. If Nullable were to treat pointers 
> differently so that isNull were true if the value were null 
> instead of using a separate bool, then you'd have to special 
> case Nullable in generic code again, because you could no 
> longer rely on assigning a value to Nullable meaning that it 
> had a value.

So for this naturally nullable type, would you say it has a value?

int* ptr = null;

> n = value;
> return n.get;
>
> could then actually fail the assertion in get if the code was 
> instantiated with a type that was naturally nullable. The 
> current approach - regardless of the name of Nullable - 
> prevents that problem.

When would you ever want to use get() if you know isNull is true 
(including for if isNull() returned true for pointers that have a 
null value) ?

> Having a Nullable treat pointers differently from value types 
> would completely defeat the purpose of having Nullable work 
> with pointers in the first place, and if you're not writing 
> generic code, a Nullable that doesn't have a separate bool 
> indicating whether it has a value or not is pointless for 
> pointers, because it would just be creating a wrapper that did 
> nothing that pointers don't do naturally.

Are you really saying it's pointless after the you spent a 
paragraph writing up about how it's useful to have 1 type provide 
the same interface ?

struct SomeType {
    void foo();
}

test( Nullable!SomeType() );
test( Nullable!(SomeType*) );

void test(T)(Nullable!T value) {

     if( !value.isNull() ) {
         value.get().foo()
     }
}

> As for the name, Nullable was a perfectly fine name when it 
> couldn't contain pointers. Is it a great name now that it can 
> contain pointers? No, and the documentation should probably be 
> improved to make it even clearer that Nullable has nothing to 
> do with the value of the type it contains, just about whether 
> the Nullable itself is "null," but the way that Nullable works 
> is the way that it should work - regardless of its name. If we 
> were adding Nullable now, we would almost certainly give it a 
> different name, but it's against Phobos policy to simply rename 
> stuff, because it breaks everything that uses the symbol when 
> you do that. If the current design caused bugs, then we might 
> replace it, because we'd be fixing and preventing bugs in the 
> process, but it doesn't. If anything, its current design 
> prevents bugs by ensuring that Nullable functions the same 
> regardless of what type it contains, making it work well in 
> generic code, whereas having Nullable treat pointers 
> differently would create bugs in generic code.

You keep saying this, but the very first version of Nullable 
could in fact contain pointers.

https://github.com/dlang/phobos/commit/0c142994d9b5cb9f379eca28f3a625c749370e4a#diff-4e008aedb3026d4a84f58323e53bf017R873

https://run.dlang.io/is/bu0hqt

Maybe there was a Nullable type in D1, but I can't find one at 
least.

> The problem with Nullable's design that does cause bugs is the 
> fact that it's aliased to its get member - which is what this 
> thread was originally about - and the way to fix that is to 
> deprecate the alias, thereby only breaking code that uses the 
> alias. There's no need to break _all_ code that uses Nullable, 
> which is exactly what would happen if we were to rename it - 
> which is why we don't rename things in Phobos anymore just 
> because it's thought that the name isn't as good as it could be.

I don't think you would break that much code if you made isNull() 
return true if the value is nullable and is actually null. Any 
code that is checking isNull() would also have to be checking if 
the pointer is null. Then only use the pointer if it's optional 
value is not null.

> If we decide that we need to replace something, because its 
> design is subtoptimal, and we can't fix it in place, then we 
> can end up with a new name, because we're actually adding 
> something new to replace something broken, not simply renaming 
> it. If this were 2010, then yeah, we'd probably rename it (e.g. 
> a number of years ago, I fixed a bunch of the names in 
> std.string, because they didn't follow Phobos' naming 
> conventions), but Walter and Andrei no longer consider renaming 
> a construct to give it a better name worth the breakage; there 
> was already tons of complaining about that when we did it when 
> we had a much smaller user base. It would be much worse now.
>
> So, if there's a fix that we're going to do at this point, it's 
> to improve Nullable's documentation, not to rename it.
>
> - Jonathan M Davis

Don't have to rename it, can just make it do what it actually is 
named after.




More information about the Digitalmars-d mailing list