Thread overview | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 14, 2020 What is the rationale behind enabling Nullable!T to be used as a regular T? | ||||
---|---|---|---|---|
| ||||
Nullable!T, as I understand is somewhat similar to Rust's Option<T>. It's meant to be an alternative to sentinel value based error checking. In regular Rust code if you do something like let x: Option<i32> = None; println!("{}", x + 4); It should throw compile error, since the `x` in `x + 4` is not checked for null. OpAdd<rhs = i32> is not implemented for Option<i32> for that reason. Of course, you can get the value using the unwrap() method, which would create runtime crash for null option. However when typing-out "unwrap()" you understand what you are signing up for. Back to D. const Nullable!int a; assert(a.isNull); writeln(a + 4); // compiles with 0 warnings Why is opBinary implemented for Nullable!T? Doesn't it defeat its purpose? |
February 14, 2020 Re: What is the rationale behind enabling Nullable!T to be used as a regular T? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adnan | On Friday, 14 February 2020 at 08:54:41 UTC, Adnan wrote: > What is the rationale behind enabling Nullable!T to be used as a regular T? The rationale is we have a few more months to wait before the deprecation period for that functionality runs out and we can remove it. :) > Back to D. > > const Nullable!int a; > assert(a.isNull); > writeln(a + 4); // compiles with 0 warnings > > Why is opBinary implemented for Nullable!T? Doesn't it defeat its purpose? If you switch to 2.090.1, you will get warnings there. If you run with -de, the warnings will be errors. --- The original reason was I believe that Nullable was never really intended to be Optional, it was intended to give types a "null" state like objects and pointers. Well, objects and pointers crash when you access them if they're null, so... (No, it's not a very good reason.) |
February 14, 2020 Re: What is the rationale behind enabling Nullable!T to be used as a regular T? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adnan | There's also the 'optional' package if you're looking for something more functional-program-ey: https://code.dlang.org/packages/optional |
February 14, 2020 Re: What is the rationale behind enabling Nullable!T to be used as a regular T? | ||||
---|---|---|---|---|
| ||||
Posted in reply to DanielG | On Friday, 14 February 2020 at 10:35:52 UTC, DanielG wrote:
> There's also the 'optional' package if you're looking for something more functional-program-ey:
>
> https://code.dlang.org/packages/optional
Not sure if this is any better
/+dub.sdl:
dependency "optional" version="~>1.0.0"
+/
import optional;
void main(const string[] args) {
static import std;
const auto n = no!int();
std.writeln(n + 4); // []
}
|
February 14, 2020 Re: What is the rationale behind enabling Nullable!T to be used as a regular T? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adnan | On Friday, 14 February 2020 at 12:40:54 UTC, Adnan wrote: > On Friday, 14 February 2020 at 10:35:52 UTC, DanielG wrote: >> There's also the 'optional' package if you're looking for something more functional-program-ey: >> >> https://code.dlang.org/packages/optional > > Not sure if this is any better > > /+dub.sdl: > dependency "optional" version="~>1.0.0" > +/ > import optional; > > void main(const string[] args) { > static import std; > const auto n = no!int(); > std.writeln(n + 4); // [] > } It's by design. optional presents a range interface of length 0 or 1. See the docs for more info: https://github.com/aliak00/optional/#summary |
February 14, 2020 Re: What is the rationale behind enabling Nullable!T to be used as a regular T? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adnan | On Friday, 14 February 2020 at 08:54:41 UTC, Adnan wrote: > Nullable!T, as I understand is somewhat similar to Rust's Option<T>. It's meant to be an alternative to sentinel value based error checking. > > In regular Rust code if you do something like > > let x: Option<i32> = None; > println!("{}", x + 4); > > It should throw compile error, since the `x` in `x + 4` is not checked for null. OpAdd<rhs = i32> is not implemented for Option<i32> for that reason. The two ends of the design spectrum (as I see it) are: 1. `Optional(T) x` as a range of [0,1] elements of type `T`. For all possible operations `op` on type `T` there exists an operation `Option(T).op` and the effect of executing is equivalent to `x.map!fun`. This is what aliak's optional package provides. 2. `Optional(T) x` behaves like a null-able pointer. The compiler statically prevents dereferencing if it can't prove that x is non-null. Such as scheme (although limited to just pointers for now) is work in progress: https://github.com/dlang/dmd/blob/master/changelog/ob.md |
February 14, 2020 Re: What is the rationale behind enabling Nullable!T to be used as a regular T? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Petar Kirov [ZombineDev] | On Friday, 14 February 2020 at 14:43:22 UTC, Petar Kirov [ZombineDev] wrote:
>
> The two ends of the design spectrum (as I see it) are:
> 1. `Optional(T) x` as a range of [0,1] elements of type `T`. For all possible operations `op` on type `T` there exists an operation `Option(T).op` and the effect of executing is equivalent to `x.map!fun`.
Edit: `x.map!op`.
|
February 14, 2020 Re: What is the rationale behind enabling Nullable!T to be used as a regular T? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adnan | On Friday, 14 February 2020 at 12:40:54 UTC, Adnan wrote:
> On Friday, 14 February 2020 at 10:35:52 UTC, DanielG wrote:
>> There's also the 'optional' package if you're looking for something more functional-program-ey:
>>
>> https://code.dlang.org/packages/optional
>
> Not sure if this is any better
>
> /+dub.sdl:
> dependency "optional" version="~>1.0.0"
> +/
> import optional;
>
> void main(const string[] args) {
> static import std;
> const auto n = no!int();
> std.writeln(n + 4); // []
> }
With std.typecons post deprecation:
import std.typecons;
void main() {
static import std;
const auto n = Nullable!int();
std.writeln(n.apply!(i => i + 4)); // Nullable!int()
}
|
February 14, 2020 Re: What is the rationale behind enabling Nullable!T to be used as a regular T? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adnan | On Friday, 14 February 2020 at 08:54:41 UTC, Adnan wrote: > Nullable!T, as I understand is somewhat similar to Rust's Option<T>. It's meant to be an alternative to sentinel value based error checking. Not exactly, as others have mentioned. But there is https://github.com/moon-chilled/tenbots-opensource/blob/master/maybe.d (which originally comes from https://github.com/dkhasel/maybe-d, but I cleaned it up a bit). At one point, I wrote a wrapper which would let you write a function with a return type of Maybe!T, but which actually returned objects of type T. But that was a giant hack and not at all worth it. |
February 14, 2020 Re: What is the rationale behind enabling Nullable!T to be used as a regular T? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Petar Kirov [ZombineDev] | On Friday, 14 February 2020 at 14:43:22 UTC, Petar Kirov [ZombineDev] wrote: > On Friday, 14 February 2020 at 08:54:41 UTC, Adnan wrote: > The two ends of the design spectrum (as I see it) are: > 1. `Optional(T) x` as a range of [0,1] elements of type `T`. For all possible operations `op` on type `T` there exists an operation `Option(T).op` and the effect of executing is equivalent to `x.map!fun`. This is what aliak's optional package provides. Very interesting. I always thought that Option<T> is a type-guard for enforced null checks (I could be wrong here). But seems to me that this design circles back to square 1: having the callee remember to check if the length of the range is 0 or 1. Which is essentially similar to check sentinel values (i.e. check if the binarysearch returns -1 as index). What languages do this? What does Aliak's package provide that's fundamentally different to just returning a T[]? Empty T[] would mean `None` and a T[] with 1 item means `Some(T)`? > 2. `Optional(T) x` behaves like a null-able pointer. The compiler statically prevents dereferencing if it can't prove that x is non-null. Such as scheme Nim's optional works this way too: import options let v = none(int) echo v + 4 # error Scala: val a: Option[Int] = None println(a + 4) // compile error Even C++: #include <iostream> #include <optional> auto main() -> int { std::optional<int> a; std::cout << a + 4 << std::endl; // compile error } >(although limited to just > pointers for now) is work in progress: > https://github.com/dlang/dmd/blob/master/changelog/ob.md Nice, any chance it's going to work with non-ptrs too? |
Copyright © 1999-2021 by the D Language Foundation