Current sentiment on Nullable.get

Jonathan M Davis newsgroup.d at jmdavisprog.com
Fri Dec 14 23:08:30 UTC 2018


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.

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.

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.

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.

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.

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





More information about the Digitalmars-d mailing list