Jump to page: 1 2
Thread overview
Nullable with reference types
Jun 29, 2015
sigod
Jun 29, 2015
Gary Willoughby
Jun 30, 2015
Meta
Jun 30, 2015
Marc Schütz
Jun 30, 2015
Meta
Jun 30, 2015
Jonathan M Davis
Jun 30, 2015
Meta
Jul 01, 2015
Jonathan M Davis
Jul 01, 2015
Marc Schütz
Jul 01, 2015
Jonathan M Davis
June 29, 2015
Hi, everyone.

```
import std.typecons : Nullable;

class Test {}

Nullable!Test test;
assert(test.isNull);
```

Why does `Nullable` allowed to be used with reference types (e.g. classes)?

P.S. I have experience with C#, where `Nullable<T>` cannot be used with reference types. And it sounds logical to me.
June 29, 2015
On Monday, 29 June 2015 at 19:29:37 UTC, sigod wrote:
> Hi, everyone.
>
> ```
> import std.typecons : Nullable;
>
> class Test {}
>
> Nullable!Test test;
> assert(test.isNull);
> ```
>
> Why does `Nullable` allowed to be used with reference types (e.g. classes)?
>
> P.S. I have experience with C#, where `Nullable<T>` cannot be used with reference types. And it sounds logical to me.

It does feel wrong but there is another feature of Nullable where you can define the value of null. Which might be handy in some cases where you don't want a reference type to actually be null? I don't know if this is the case but it may be useful.
June 30, 2015
On Monday, 29 June 2015 at 19:29:37 UTC, sigod wrote:
> Hi, everyone.
>
> ```
> import std.typecons : Nullable;
>
> class Test {}
>
> Nullable!Test test;
> assert(test.isNull);
> ```
>
> Why does `Nullable` allowed to be used with reference types (e.g. classes)?
>
> P.S. I have experience with C#, where `Nullable<T>` cannot be used with reference types. And it sounds logical to me.

It's a design mistake in Nullable. I would suggest that either never use Nullable with a type that already has a null value, or use the "overload" of Nullable that takes a null value, and set it to null. Example:

Class Test {}
alias NullableTest = Nullable!(Test, null);
June 30, 2015
On Tuesday, 30 June 2015 at 00:02:38 UTC, Meta wrote:
> It's a design mistake in Nullable. I would suggest that either never use Nullable with a type that already has a null value, or use the "overload" of Nullable that takes a null value, and set it to null. Example:
>
> Class Test {}
> alias NullableTest = Nullable!(Test, null);

Can we not specialize the other overload for references, pointers, and maybe slices?
June 30, 2015
On Tuesday, 30 June 2015 at 11:50:19 UTC, Marc Schütz wrote:
> On Tuesday, 30 June 2015 at 00:02:38 UTC, Meta wrote:
>> It's a design mistake in Nullable. I would suggest that either never use Nullable with a type that already has a null value, or use the "overload" of Nullable that takes a null value, and set it to null. Example:
>>
>> Class Test {}
>> alias NullableTest = Nullable!(Test, null);
>
> Can we not specialize the other overload for references, pointers, and maybe slices?

Not now, as that would break code relying on this behaviour. I've created a replacement for Nullable that does this, though, and it works quite well.
June 30, 2015
On Tuesday, 30 June 2015 at 00:02:38 UTC, Meta wrote:
> On Monday, 29 June 2015 at 19:29:37 UTC, sigod wrote:
>> Hi, everyone.
>>
>> ```
>> import std.typecons : Nullable;
>>
>> class Test {}
>>
>> Nullable!Test test;
>> assert(test.isNull);
>> ```
>>
>> Why does `Nullable` allowed to be used with reference types (e.g. classes)?
>>
>> P.S. I have experience with C#, where `Nullable<T>` cannot be used with reference types. And it sounds logical to me.
>
> It's a design mistake in Nullable. I would suggest that either never use Nullable with a type that already has a null value, or use the "overload" of Nullable that takes a null value, and set it to null. Example:
>
> Class Test {}
> alias NullableTest = Nullable!(Test, null);

I tend to think that it's incredibly stupid to use something like Nullable for a type that's already Nullable. It's just silly. If a type is already nullable, then just use that and stop being adding extra overhead for no good reason. However, it _is_ true that if you need to have a nullable variable in generic code where the type that you need to be nullable could be any type, then having Nullable work with all types - and work with them all in the same way - is useful. Without that, you'd have to special case your code for types which were naturally nullable (and thus used null) and those which required Nullable. So, I can see why it could be useful to have Nullable work with classes, but I also question how common such a use case is.

- Jonathan M Davis
June 30, 2015
On Tuesday, 30 June 2015 at 15:17:00 UTC, Jonathan M Davis wrote:
> I tend to think that it's incredibly stupid to use something like Nullable for a type that's already Nullable.

Unfortunately, we're stuck with it as changing that would break code.

> It's just silly. If a type is already nullable, then just use that and stop being adding extra overhead for no good reason.

I agree. There are several minuscule advantages you get from wrapping a nullable type with Nullable, but they're almost negligible.


June 30, 2015
On 6/30/15 11:16 AM, Jonathan M Davis wrote:
> On Tuesday, 30 June 2015 at 00:02:38 UTC, Meta wrote:
>> On Monday, 29 June 2015 at 19:29:37 UTC, sigod wrote:
>>> Hi, everyone.
>>>
>>> ```
>>> import std.typecons : Nullable;
>>>
>>> class Test {}
>>>
>>> Nullable!Test test;
>>> assert(test.isNull);
>>> ```
>>>
>>> Why does `Nullable` allowed to be used with reference types (e.g.
>>> classes)?
>>>
>>> P.S. I have experience with C#, where `Nullable<T>` cannot be used
>>> with reference types. And it sounds logical to me.
>>
>> It's a design mistake in Nullable. I would suggest that either never
>> use Nullable with a type that already has a null value, or use the
>> "overload" of Nullable that takes a null value, and set it to null.
>> Example:
>>
>> Class Test {}
>> alias NullableTest = Nullable!(Test, null);
>
> I tend to think that it's incredibly stupid to use something like
> Nullable for a type that's already Nullable. It's just silly. If a type
> is already nullable, then just use that and stop being adding extra
> overhead for no good reason. However, it _is_ true that if you need to
> have a nullable variable in generic code where the type that you need to
> be nullable could be any type, then having Nullable work with all types
> - and work with them all in the same way - is useful. Without that,
> you'd have to special case your code for types which were naturally
> nullable (and thus used null) and those which required Nullable. So, I
> can see why it could be useful to have Nullable work with classes, but I
> also question how common such a use case is.

I know this is just back-of-envelope, but what's wrong with:

alias Nullable(T) if(is(T == class)) = T;

bool isNull(T)(T t) if(is(T == class)) { return t is null;}

?

-Steve
July 01, 2015
On Tuesday, June 30, 2015 14:29:52 Steven Schveighoffer via Digitalmars-d-learn wrote:
> I know this is just back-of-envelope, but what's wrong with:
>
> alias Nullable(T) if(is(T == class)) = T;
>
> bool isNull(T)(T t) if(is(T == class)) { return t is null;}

In principle, there's no reason why we can'd do something like that. It's essentially what we do with the take and its return type (though that doesn't require a free function for additional functionality). The question would be whether it would break code to do so and whether it would be worth the breakage if we did.

- Jonathan M Davis

July 01, 2015
On Tuesday, 30 June 2015 at 18:29:31 UTC, Steven Schveighoffer wrote:
> I know this is just back-of-envelope, but what's wrong with:
>
> alias Nullable(T) if(is(T == class)) = T;
>
> bool isNull(T)(T t) if(is(T == class)) { return t is null;}

That's what I intended. (Same for pointers and slices, BTW.)

I does however have a slightly different behaviour: In the current implementation, there can be instances for which `isNull` returns false, but whose payloads are nevertheless `null`.
« First   ‹ Prev
1 2