Current sentiment on Nullable.get
Rubn
where at is.this
Fri Dec 14 22:34:56 UTC 2018
On Thursday, 13 December 2018 at 13:47:34 UTC, Jonathan M Davis
wrote:
> On Thursday, December 13, 2018 4:41:01 AM MST aliak via
> Digitalmars-d wrote:
>> On Tuesday, 11 December 2018 at 22:32:45 UTC, Jonathan M Davis
>>
>> wrote:
>> > Ultimately, allocation is the main difference here. Nullable
>> > provides a way to emulate the behavior of a pointer with
>> > regards to nullability without having to allocate on the
>> > heap. An Optional or Maybe type is ultimately the same
>> > thing, just with a different name. If it weren't for the
>> > issue of heap allocation, it could easily argued that
>> > pointers negate the need for any kind of
>> > Nullable/Optional/Maybe type, because they provide that
>> > functionality. And they don't even cause memory safety
>> > issues if you're not doing pointer arithmetic. So, really, I
>> > think that the need for heap allocation is _exactly_ the
>> > issue here that these types are designed to solve and that
>> > without that, a Nullable/Optional/Maybe type isn't adding
>> > much.
>>
>> This is not the point of optional types. They're just there to
>> denote if a value exists or not.
>
> 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.
>
>> > At most, it's making it clear that it's expected that the
>> > value can be null/empty/missing, because not all functions
>> > that involve pointers consider null to be an acceptable
>> > value.
>>
>> That makes a big difference. With everything. Writing the
>> code, maintaining code, reviewing code, coming back to code,
>> getting in to a language. Principle of least surprises.
>> Intuitiveness. These all matter:
>>
>> class C {}
>> struct S {}
>>
>> * What is Nullable!(int*)? An int * that can be null? But
>> wait...
>> * What is Nullable!C? A reference type that can be null? Isn't
>> that just "C" ? What is this adding? How does this make sense?
>> * What does this do: "Nullable!C a = null; a.isNull;"? if it's
>> false does that mean C exists? So C exists?
>> * What is Nullable!S? A struct that can be null or a struct
>> that
>> may exist? Or was it just to avoid heap allocation?
>> * What's the difference between null and any of those other
>> types' isNull?
>> * Nullable!C a = null; a.get; // should that throw/assert?
>>
>> These are all non-obvious.
>
> 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.
>
> 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.
>
> 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
> 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? The only issue
> with it that I see is that the fact that it's aliased to its
> get member risks bugs when you change code that used a T to use
> Nullable!T. Without that alias, you'd be forced to update the
> code and make sure that it could handle when isNull was true,
> whereas right now, it can be trivial to just change a
> variable's type from T to Nullable!T and assume that it works,
> and even if you're careful and try to make the code use get and
> isNull properly, you can easily miss a place where the alias is
> used and end up with a bug. But if the alias is removed like
> the OP wants, then that entire problem goes away, and then I
> don't see why Nullable would cause subtle bugs.
>
> I'll grant you that now that Nullable allows types which are
> naturally nullable, the name is worse, because it does
> sometimes cause confusion around isNull. But it's against
> current policy to rename stuff in Phobos simply to give it a
> better name, and if the documentation is improved, that problem
> should largely go away. At that point, the only folks who would
> be confused are those that don't read the docs, and folks who
> don't read the documentation for the code they're reading or
> maintaining are going to be confused in general. If we were to
> start over, then yeah, it should probably be named Optional or
> Maybe or whatever rather than Nullable given that it accepts
> naturally nullable types, but I fail to see how its design
> causes bugs aside from the problems caused by the alias. And we
> should be able to fix that via deprecation, only breaking code
> that arguably should be broken in the process, whereas renaming
> stuff breaks _all_ code using Nullable, the vast majority of
> which is perfectly fine - which is why Walter and Andrei are
> against allowing renaming stuff. It breaks tons of code, and in
> general, the benefit is highly subjective if not outright
> negligible. It's probably worth more in this case than in many
> other cases, but it would still involve breaking tons of
> perfectly valid code.
>
> - Jonathan M Davis
https://github.com/dlang/phobos/commit/bfa6cd72ae83a977f272bf3520f3ef5da99eb7cf#diff-4e008aedb3026d4a84f58323e53bf017R1862
Had a good laugh when I found this. Looks like someone just
didn't know what they were doing and someone was picking up their
pieces.
More information about the Digitalmars-d
mailing list