Re: Is there a simple way to check if value is null for every case?
On Monday, 27 August 2018 at 21:48:04 UTC, Alex wrote: On Monday, 27 August 2018 at 19:36:29 UTC, aliak wrote: Then Nullable!(int*) would be the same as int*. Or even better maybe is to give a compiler error when you try and stuff a nullable type inside a Nullable. Because ... why? Isn't it arguable, whether this is desired? I mean, in the present state you can separate the cases, whether the Nullable is set or not. This is a feature. If Nullable!(int*) behaves like int*, it would be somewhat more straight forward, which is maybe also a feature. But you loose something you can do right now... Certainly arguable :) I'm unsure about of what you lose is worth having, is the problem. And I have trouble thinking of a use case? If we implement opEquals(typeof(null)) as is now, then this code: Nullable!(int*) n = null; assert(n != null); passes. And if we have no opEquals then we can't test for native null on a 'null'able type O_o Another options is: bool opEquals(typeof(null)) { enum isNullInvalid = is(T == class) || is(T == interface) || isSomeFunction!T; static if (isNullInvalid) return isNull || data is null else return isNull; } I also did a quick search on google "allintext: "nullable" site:github.com filetype:d" and there were 0 instances of T* (just looked thorugh search results didn't click in).
Re: Is there a simple way to check if value is null for every case?
On Monday, 27 August 2018 at 19:36:29 UTC, aliak wrote: Then Nullable!(int*) would be the same as int*. Or even better maybe is to give a compiler error when you try and stuff a nullable type inside a Nullable. Because ... why? Isn't it arguable, whether this is desired? I mean, in the present state you can separate the cases, whether the Nullable is set or not. This is a feature. If Nullable!(int*) behaves like int*, it would be somewhat more straight forward, which is maybe also a feature. But you loose something you can do right now...
Re: Is there a simple way to check if value is null for every case?
On Monday, 27 August 2018 at 14:11:32 UTC, SG wrote: On Monday, 27 August 2018 at 13:02:28 UTC, rikki cattermole wrote: So Nullable in D and C# is basically the same except C#'s has language support. The big difference is that in there I could do: int? i = null; string j = null; var k = null; and test all like: i == null; j == null; k == null; but in D: Nullable!int i; auto j = null; string k = null; writefln("%s", i.isNull); // I need to invoke Nullable property isNull; writefln("%s", i == null); // I can't just do this. writefln("%s", j == null); writefln("%s", k == null); I hear you. IMO Nullable should be modified a bit to serve the purpose of turning non-nullable types in to nullable types and only that (right now it's confusing itself with an optional type). Then we could implement opEquals(typeof(null)) so that nullable == null would work. I.e. struct Nullable(T) { static if (isPointer!T) { private PointerTarget!T _value = PointerTarget!T.init; } else { private T _value = T.init; } bool opEquals(typeof(null)) { return isNull; } } Then Nullable!(int*) would be the same as int*. Or even better maybe is to give a compiler error when you try and stuff a nullable type inside a Nullable. Because ... why? Cheers, - Ali
Re: Is there a simple way to check if value is null for every case?
On Monday, 27 August 2018 at 14:11:32 UTC, SG wrote: On Monday, 27 August 2018 at 13:02:28 UTC, rikki cattermole wrote: So Nullable in D and C# is basically the same except C#'s has language support. Shouldn't it be in the standard library? I think it's worth it to create a feature request in Phobos for that. Or at least make a bug report. Such inconsistencies must be handled by a standard library, not manually, I believe.
Re: Is there a simple way to check if value is null for every case?
On Monday, 27 August 2018 at 13:02:28 UTC, rikki cattermole wrote: So Nullable in D and C# is basically the same except C#'s has language support. The big difference is that in there I could do: int? i = null; string j = null; var k = null; and test all like: i == null; j == null; k == null; but in D: Nullable!int i; auto j = null; string k = null; writefln("%s", i.isNull); // I need to invoke Nullable property isNull; writefln("%s", i == null); // I can't just do this. writefln("%s", j == null); writefln("%s", k == null);
Re: Is there a simple way to check if value is null for every case?
On Monday, 27 August 2018 at 12:54:59 UTC, SG wrote: On Monday, 27 August 2018 at 03:21:04 UTC, rikki cattermole wrote: Templates make it the easiest way, since common patterns, like arrays, classes and pointers have the exact same null check syntax. I see. That code is only for classes. C# also has structs which are a value type. Which it would not work for. The same thing for struct in C# Struct S{ public int? i; } S.i == null; // This works nicely. You don't need isNull function for Nullable because it has a method called it. That will be preferred (hence I specifically used isNull as the name). For Variant, use hasValue. bool isNull(Variant value) { return !value.hasValue; } The problem I'm trying to solve is beyond that. This is just an example. But bear with me, right now all I want is a function to check the value from 'a' type and return if it is null. The type could be a: Class, Struct, a Basic data type, Variant, Nullable and so. And what I see, these types has different behaviors, while in C# at least for this same case, I would write the same thing in few lines to perform it, in D I found very hard. Isn't counter intuitive the way D works? Because for each type Class/Nullable you check with .isNull, for Variant with .hasValue, for string (variable is null). Thanks. hasValue isn't equivalent of isNull or is null. 'null' is valid value in Variant: import std.variant; Variant v; v = null; assert(v.hasValue);//v has value assert(v.get!(typeof(null)) is null); //value in v is null Nullable!T.isNull isn't equivalent of is null: int* i = null; Nullable!(int*) ni; ni = i; assert(ni.isNull == false); ///ni has value assert(ni is null); ///ni value is null string is null isn't equivalent of empty: string str = "test"; str = str[0 .. 0]; assert(str !is null); ///str isn't null assert(str.empty); ///str is empty
Re: Is there a simple way to check if value is null for every case?
On 28/08/2018 12:54 AM, SG wrote: The same thing for struct in C# Struct S{ public int? i; } S.i == null; // This works nicely. https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/nullable-types/index So Nullable in D and C# is basically the same except C#'s has language support.
Re: Is there a simple way to check if value is null for every case?
On Monday, 27 August 2018 at 03:21:04 UTC, rikki cattermole wrote: Templates make it the easiest way, since common patterns, like arrays, classes and pointers have the exact same null check syntax. I see. That code is only for classes. C# also has structs which are a value type. Which it would not work for. The same thing for struct in C# Struct S{ public int? i; } S.i == null; // This works nicely. You don't need isNull function for Nullable because it has a method called it. That will be preferred (hence I specifically used isNull as the name). For Variant, use hasValue. bool isNull(Variant value) { return !value.hasValue; } The problem I'm trying to solve is beyond that. This is just an example. But bear with me, right now all I want is a function to check the value from 'a' type and return if it is null. The type could be a: Class, Struct, a Basic data type, Variant, Nullable and so. And what I see, these types has different behaviors, while in C# at least for this same case, I would write the same thing in few lines to perform it, in D I found very hard. Isn't counter intuitive the way D works? Because for each type Class/Nullable you check with .isNull, for Variant with .hasValue, for string (variable is null). Thanks.
Re: Is there a simple way to check if value is null for every case?
On 27/08/2018 12:51 PM, SG wrote: On Sunday, 26 August 2018 at 16:39:53 UTC, rikki cattermole wrote: UFCS function called isNull. e.g. import std.traits : isPointer; bool isNull(T)(T value) if (is(T == class) || isPointer!T) { return value is null; } Hi Rikki, I'm still confused, I want to create a extension for checking null for every type, so in D I'll need to handle each case with Templates? Templates make it the easiest way, since common patterns, like arrays, classes and pointers have the exact same null check syntax. Because in C# I just need to compare an object/variable with null, x == null; myObject == null; myObject.i == null; myStruct == null; myStruct.j == null; This works fine in C#. That code is only for classes. C# also has structs which are a value type. Which it would not work for. But again, in D I'll need the check the type? Is possible to make one Template for all cases? The code below works, but I don't think this is a right thing to do, right? You don't need isNull function for Nullable because it has a method called it. That will be preferred (hence I specifically used isNull as the name). For Variant, use hasValue. bool isNull(Variant value) { return !value.hasValue; } Writing a Unified Function Call Syntax function isn't really an extension. You're defining a function that is to be preferred when you ask for a method of the same name. So that it appears as if it was actually described as a method instead of a free-function (not attached to class/interface/struct/union).
Re: Is there a simple way to check if value is null for every case?
On Sunday, 26 August 2018 at 16:39:53 UTC, rikki cattermole wrote: UFCS function called isNull. e.g. import std.traits : isPointer; bool isNull(T)(T value) if (is(T == class) || isPointer!T) { return value is null; } Hi Rikki, I'm still confused, I want to create a extension for checking null for every type, so in D I'll need to handle each case with Templates? Because in C# I just need to compare an object/variable with null, x == null; myObject == null; myObject.i == null; myStruct == null; myStruct.j == null; This works fine in C#. But again, in D I'll need the check the type? Is possible to make one Template for all cases? The code below works, but I don't think this is a right thing to do, right? import std.stdio, std.typecons, std.variant, std.conv; import std.traits : isPointer; bool foo(T)(T value) if (is(T == VariantN!32LU)) { return value == null; } bool foo(T)(T value) if (is(T == Nullable!int) || isPointer!T) { return value.isNull; } bool foo(T)(T t) if (!is(T == Nullable!int) && !is(T == VariantN!32LU)){ if (is(T == typeof(null))){ return true; } return (t is null); } class S{ Nullable!int i; } void main(){ Variant v = null; writeln(v == null," - " ,v.foo); Variant v2 = "a"; writeln(v2 == null," - " ,v2.foo); string x = "a"; writeln(x is null," - " ,x.foo); string y = null; writeln(y is null," - ", y.foo); auto z = null; writeln(z is null," - ", z.foo); S s = new S(); writeln(s.i.isNull," - ", s.i.foo); }
Is there a simple way to check if value is null for every case?
Hi again, The code below works for some cases but not for the Nullable!Type. A way to fix it should be check the type and use ".isNull" for Nullabe!Type. But is there a simple way to test if value is null for every case? import std.stdio, std.typecons, std.variant, std.conv; bool foo(T)(T t){ return (t is null); } class S{ Nullable!int i; } void main(){ string x = "a"; writeln(x is null," - " ,x.foo); string y = null; writeln(y is null," - ", y.foo); auto z = null; writeln(z is null," - ", z.foo); S s = new S(); writeln(s.i.isNull); // Ok //writeln(s.i is null); // Error //s.i.foo(2); // Error }
Re: Is there a simple way to check if value is null for every case?
On 27/08/2018 4:37 AM, SG wrote: Hi again, The code below works for some cases but not for the Nullable!Type. A way to fix it should be check the type and use ".isNull" for Nullabe!Type. But is there a simple way to test if value is null for every case? import std.stdio, std.typecons, std.variant, std.conv; bool foo(T)(T t){ return (t is null); } class S{ Nullable!int i; } void main(){ string x = "a"; writeln(x is null," - " ,x.foo); string y = null; writeln(y is null," - ", y.foo); auto z = null; writeln(z is null," - ", z.foo); S s = new S(); writeln(s.i.isNull); // Ok //writeln(s.i is null); // Error //s.i.foo(2); // Error } UFCS function called isNull. e.g. import std.traits : isPointer; bool isNull(T)(T value) if (is(T == class) || isPointer!T) { return value is null; }