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". -SteveYou'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