digitalmars.D.learn - Is there a simple way to check if value is null for every case?
- SG (24/24) Aug 26 2018 Hi again,
- rikki cattermole (7/43) Aug 26 2018 UFCS function called isNull.
- SG (48/54) Aug 26 2018 Hi Rikki,
- rikki cattermole (17/44) Aug 26 2018 Templates make it the easiest way, since common patterns, like arrays,
- SG (19/31) Aug 27 2018 The same thing for struct in C#
- rikki cattermole (4/11) Aug 27 2018 https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/nullabl...
- SG (18/20) Aug 27 2018 The big difference is that in there I could do:
- Jacob Shtokolov (6/10) Aug 27 2018 Shouldn't it be in the standard library?
- aliak (22/43) Aug 27 2018 I hear you. IMO Nullable should be modified a bit to serve the
- vit (20/54) Aug 27 2018 hasValue isn't equivalent of isNull or is null. 'null' is valid
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 }
Aug 26 2018
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; }
Aug 26 2018
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? x == null; myObject == null; myObject.i == null; myStruct == null; myStruct.j == null; 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); }
Aug 26 2018
On 27/08/2018 12:51 PM, SG wrote:On Sunday, 26 August 2018 at 16:39:53 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.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?x == null; myObject == null; myObject.i == null; myStruct == null; myStruct.j == null;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).
Aug 26 2018
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.value type. Which it would not work for.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. 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.
Aug 27 2018
On 28/08/2018 12:54 AM, SG wrote:Struct S{ public int? i; } S.i == null; // This works nicely.https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/nullable-types/index support.
Aug 27 2018
On Monday, 27 August 2018 at 13:02:28 UTC, rikki cattermole wrote: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);
Aug 27 2018
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: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.language support.
Aug 27 2018
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: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, - Alilanguage 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);
Aug 27 2018
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...
Aug 27 2018
On Monday, 27 August 2018 at 21:48:04 UTC, Alex wrote:On Monday, 27 August 2018 at 19:36:29 UTC, aliak wrote: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).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...
Aug 27 2018
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: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 emptyTemplates make it the easiest way, since common patterns, like arrays, classes and pointers have the exact same null check syntax.I see.value type. Which it would not work for.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 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.
Aug 27 2018