-
-
Notifications
You must be signed in to change notification settings - Fork 747
Fix issue 17440: Nullable!Class should redirect to Nullable!(Class,null) #6038
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The current implementation of `Nullable!T` (the overload with a single type parameter) is clearly designed for types T with by-value semantics, as evidenced by the use of `.destroy` in `.nullify`, along with other implementation decisions. As a result, nullifying a `Nullable!Class` also triggers destruction of the class object, which is surprising behaviour. Furthermore, since class references already have a null state, `Nullable!Class` adds a second, distinct null state, which only add to the confusion. Since there's a second overload of `Nullable` that can be used for proxying a class reference's null semantics with the Nullable API (i.e., `isNull` and `nullify`), simply forward instantiations of `Nullable!Class` to `Nullable!(Class, null)` instead. An alternative fix is to change `.nullify` so that it does not call `.destroy` on class references. However, this does not solve the problem of confusion caused by introducing two distinct null states in `Nullable!Class`. As for why one would use `Nullable` on a type that already has a null state, to quote a comment from the bugzilla issue: For those confused as to why you'd want to wrap a Nullable around something that already has nullable semantics, it's mostly about making APIs that explicitly declare their optional return values. See: http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html
|
P.S. For ease of review, use this link with whitespace changes ignored: https://github.com/dlang/phobos/pull/6038/files?w=1 |
|
Seems reasonable. I think this is a great opportunity to document why the nullable class option exists as well, making sure to mention |
wilzbach
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that calling .nullify for reference types is a bug.
Though for the record - people could depend on the old behavior of |
|
Calling destroy on class instances from .nullify is a huge mistake IMO, but we really can't change that now. Likewise, I'm all for this, but I think it needs to be deprecated for a few releases first (i.e., |
|
Hmph. So should we deprecate While cooking up a nice ddoc'd unittest example for using classes with In order to make it work, you'd have to make It works, but requires patching all code that references |
|
Not to mention, :-( Looking at the code and docs, it seems that both overloads of |
|
Blocking for the time being until we decide on an appropriate solution to this mess. |
|
@quickfur yup, |
|
Is there a list of issues somewhere that I can take a look at? Or is it just searching for nullable on bugzilla? I'm almost tempted to write a proper |
|
Searching |
I remember the following two PRs being related to Nullable / Option / Maybe as
There's also at least this issue at Vibe.d: |
|
OK, looks like fixing this is going to be far more complicated than I anticipated. Maybe somebody else should take this up. :-P |
|
This should be pretty simple -- nullify should set the value to null, and not destroy the class object. It's what happens for a pointer or array as well. It's just that destroy on class types will call the destructor.
Meh, the GC will get to it eventually :) |
|
@schveiguy I was hoping to avoid that route, because it means |
|
Reboot: #6043 |
I'll just respond to this point here: I think this is not only fine, but expected. Why else would you want to create such a type? Typically, when I'm using I think the biggest problem is that it's called |
|
Haha, well, it's not really for whatever use you deem fit; the code is such that you cannot access the underlying data when the bool is false. So it is some kind of null or not-present state. Given that, I have a hard time understanding the need to use The reason stated in the bug was to explicitly document APIs that return an optional value; perhaps |
|
Right. Part of the problem here is that things that actual nullable types support are not supportable with a wrapper struct. You just can't hook IMO, the fact that I think it fits more with an optional type than a nullable type, which is unfortunate since the name of the type is In any case, I think deprecating |
|
Maybe it's time to write a proper |
The current implementation of
Nullable!T(the overload with a single type parameter) is clearly designed for types T with by-value semantics, as evidenced by the use of.destroyin.nullify, along with other implementation decisions. As a result, nullifying aNullable!Classalso triggers destruction of the class object, which is surprising behaviour. Furthermore, since class references already have a null state,Nullable!Classadds a second, distinct null state, which only adds to the confusion.Since there's a second overload of
Nullablethat can be used for proxying a class reference's null semantics with the Nullable API (i.e.,isNullandnullify), simply forward instantiations ofNullable!ClasstoNullable!(Class, null)instead.An alternative fix is to change
.nullifyso that it does not call.destroyon class references. However, this does not solve the problem of confusion caused by introducing two distinct null states inNullable!Class.As for why one would use
Nullableon a type that already has a null state, to quote a comment from the bugzilla issue: