digitalmars.D - The problem with Nullable: nullable(null).isNull is false.
- Piotr Mitana (33/33) Jul 25 2022 Hello. As Nullable has gained a bit recently (disabling automatic
- Timon Gehr (3/46) Jul 25 2022 Not a big fan. E.g., this ad-hoc special case would make it hard to use
- Piotr Mitana (16/18) Jul 25 2022 Could you come up with an example of use case that would be
- Steven Schveighoffer (11/48) Jul 25 2022 A counter example:
- Piotr Mitana (14/25) Jul 25 2022 You're right, this case justifies double-checking, as there are
- jfondren (15/16) Jul 26 2022 History of this poor type:
- Paul Backus (7/22) Jul 26 2022 This makes for a nice story, but doesn't actually match the
- monkyyy (3/5) Jul 31 2022 I like this story tho and need a story to believe in for why
Hello. As Nullable has gained a bit recently (disabling automatic
aliasing to content andrange interface – thanks for that!), it
needs one more improvement.
Currently:
```d
assert(nullable(null).isNull == false);
```
It's might be very misleading – to make it truly safe, an object
in nullable requires a double-check:
```d
class C {}
// ...
Nullable!C aThing = someCode()
if(!aThing.isNull && aThing.get != null) {
// Now we are safe
}
```
The simple solution is to use the `Nullable(T, nullValue)(T t)`
variant, as
```d
assert(nullable!null(null).isNull == true);
```
The solution in my opinion is:
- disable `Nullable(T)` for any type that can have `null` value,
- for `Nullable(T, T nullValue)` add default the `nullValue` to
`null` for these types, so that it replaces the `Nullable(T)`
usage.
I know that it changes code's behavior, so would require the
deprecation process probably. However, I expect the Nullable in
its current form is rarely used in conjunction with classes
because of having this exact issue. Implementing this change
would allow it to be used as a proper optional type that could
serve to prevent null-related errors.
Jul 25 2022
On 25.07.22 10:58, Piotr Mitana wrote:
Hello. As Nullable has gained a bit recently (disabling automatic
aliasing to content andrange interface – thanks for that!), it needs one
more improvement.
Currently:
```d
assert(nullable(null).isNull == false);
```
It's might be very misleading – to make it truly safe, an object in
nullable requires a double-check:
```d
class C {}
// ...
Nullable!C aThing = someCode()
if(!aThing.isNull && aThing.get != null) {
// Now we are safe
}
```
The simple solution is to use the `Nullable(T, nullValue)(T t)` variant, as
```d
assert(nullable!null(null).isNull == true);
```
The solution in my opinion is:
- disable `Nullable(T)` for any type that can have `null` value,
- for `Nullable(T, T nullValue)` add default the `nullValue` to `null`
for these types, so that it replaces the `Nullable(T)` usage.
I know that it changes code's behavior, so would require the deprecation
process probably. However, I expect the Nullable in its current form is
rarely used in conjunction with classes because of having this exact
issue. Implementing this change would allow it to be used as a proper
optional type that could serve to prevent null-related errors.
Not a big fan. E.g., this ad-hoc special case would make it hard to use
Nullable reliably in generic code.
Jul 25 2022
On Monday, 25 July 2022 at 12:04:35 UTC, Timon Gehr wrote:Not a big fan. E.g., this ad-hoc special case would make it hard to use Nullable reliably in generic code.Could you come up with an example of use case that would be problematic? I perceive Nullable as a way to add a null value to the type that does not have it by default (for example `Nullable!int` etc.). As classes and reference types already do have their `null`, The Nullable in a general case would serve as "add the null *if if there isin't one*. The `Nullable!int` and `Nullable!MyClass` both would have a single null value, which I believe will be even more convenient to use in a generic code. Also, a [library with an Optional type](https://code.dlang.org/packages/optional) has been written and in its README it actually states the problem that I have raised here. With Nullable covering this case there would be no need for this library, as Phobos' solution would be a proper solution for this problem.
Jul 25 2022
On 7/25/22 4:58 AM, Piotr Mitana wrote:
Hello. As Nullable has gained a bit recently (disabling automatic
aliasing to content andrange interface – thanks for that!), it needs one
more improvement.
Currently:
```d
assert(nullable(null).isNull == false);
```
It's might be very misleading – to make it truly safe, an object in
nullable requires a double-check:
```d
class C {}
// ...
Nullable!C aThing = someCode()
if(!aThing.isNull && aThing.get != null) {
// Now we are safe
}
```
The simple solution is to use the `Nullable(T, nullValue)(T t)` variant, as
```d
assert(nullable!null(null).isNull == true);
```
The solution in my opinion is:
- disable `Nullable(T)` for any type that can have `null` value,
- for `Nullable(T, T nullValue)` add default the `nullValue` to `null`
for these types, so that it replaces the `Nullable(T)` usage.
A counter example:
```d
Nullable!C getDBValue(int key);
auto x = getDBValue(42);
if(x.isNull) { writeln("database does not contain the requested row"); }
else if(x.get is null) { writeln("database contains the requested row,
but the value is set to NULL"); }
```
The real "problem" is that Nullable is called "Nullable".
-Steve
Jul 25 2022
On Monday, 25 July 2022 at 13:05:08 UTC, Steven Schveighoffer
wrote:
A counter example:
```d
Nullable!C getDBValue(int key);
auto x = getDBValue(42);
if(x.isNull) { writeln("database does not contain the requested
row"); }
else if(x.get is null) { writeln("database contains the
requested row, but the value is set to NULL"); }
```
The real "problem" is that Nullable is called "Nullable".
-Steve
You're right, this case justifies double-checking, as there are
two ways of not having a real value (either the given key is
absent or the value for it is `null`). Still, this is a somewhat
specific case.
But that indeed means that both these options should remain
available. Maybe an alias could be added then to differentiate it
– something like
```d
alias SmartNullable(T)(T t) = Nullable!(T, null)
```
(probably with a different name & aliasing to the plain nullable
for primitives and structs).
Jul 25 2022
On Monday, 25 July 2022 at 13:05:08 UTC, Steven Schveighoffer wrote:The real "problem" is that Nullable is called "Nullable".History of this poor type: 1. it's a way to add a Null state to a value type. You know, like Java. Very convenient type for trivial task. 2. hey! This doesn't act like an optional type/maybe monad! This is BROKEN. (convenience was deliberately broken to make it worse for the original task.) 3. hey! This acts like an optional type/maybe monad that doesn't care if the wrapped type also has something like a null state! This is BROKEN. (now proposed: deliberately break it to make it worse as an optional type.) What it needed was not code but a clear justification and context in the documentation, without assuming that people would just get it from the feature list.
Jul 26 2022
On Tuesday, 26 July 2022 at 15:21:36 UTC, jfondren wrote:On Monday, 25 July 2022 at 13:05:08 UTC, Steven Schveighoffer wrote:This makes for a nice story, but doesn't actually match the facts. Since it was introduced in 2009 [1], `Nullable` has always had a distinct `isNull` state, even for types that can already be `null`. [1] https://github.com/dlang/phobos/commit/0c142994d9#diff-81bed7f05cbd4e992067b7019125e6a1349ebe5098c6980b64bbbca8d5491e17The real "problem" is that Nullable is called "Nullable".History of this poor type: 1. it's a way to add a Null state to a value type. You know, like Java. Very convenient type for trivial task. 2. hey! This doesn't act like an optional type/maybe monad! This is BROKEN. (convenience was deliberately broken to make it worse for the original task.) 3. hey! This acts like an optional type/maybe monad that doesn't care if the wrapped type also has something like a null state! This is BROKEN. (now proposed: deliberately break it to make it worse as an optional type.)
Jul 26 2022
On Tuesday, 26 July 2022 at 15:34:20 UTC, Paul Backus wrote:This makes for a nice story, but doesn't actually match the facts.I like this story tho and need a story to believe in for why std.nullable is so so incredibly bad.
Jul 31 2022









Piotr Mitana <piotr.mitana e.email> 