Opt-in non-null class references?

aliak something at something.com
Sun Mar 11 09:28:39 UTC 2018


On Sunday, 4 March 2018 at 13:26:21 UTC, SimonN wrote:
> On Sunday, 4 March 2018 at 12:03:32 UTC, aliak wrote:
>> Maybe this part can be fixed with:
>> struct NonNull(T) if (isPointer!T || is(T == class))
>> {
>>     @disable opAssign(V)(V v) {} // no no no
>>     void opAssign(V)(NonNull!V other) { // only this allowed.
> Interesting approach -- I'll keep it on the backburner for 
> testing. Converting a class-heavy codebase to this would be 
> daunting, but I don't want to rule it out yet.

Heh yeah, it would be indeed!

> Automatic subtype detection will fail, and, thus, e.g., 
> covariant return types.
>
> To make it clearer that this isn't a bug in Optional, but 
> rather an artifact of D's subtype detection, I will give 
> examples with std.typecons.Rebindable instead of with Optional. 
> For a class A, Rebindable!(const(A)) is designed as a reference 
> to const(A) that can be rebound to point to a different 
> const(A). I believe Rebindable!A aliases itself away and thus 
> Rebindable!A will not be discussed, only Rebindable!(const(A)).
>
>     import std.typecons;
>     class Base { }
>     class Derived : Base { }
>     static assert(is(const(Derived) : const(Base))); // OK
>     static assert(is(Rebindable!(const(Derived)) : 
> Rebindable!(const(Base)))); // fails
>
> Covariant return types will also fail. The following example 
> doesn't compile, but would if we stripped all `rebindable' and 
> all `Rebindable!':
>
>     import std.typecons;
>     class Base {
>         Rebindable!(const(Base)) create()
>         {
>             return rebindable(new Base());
>         }
>     }
>     class Derived : Base {
>         override Rebindable!(const(Derived)) create()
>         {
>             return rebindable(new Derived());
>         }
>     }


Ah, thanks, that cleared things up!

Does this maybe boil down to if two templates should be covariant 
on their parameter types? Considering that static if allows you 
to do whatever you want inside based on static inference, in 
theory Rebindable!(const Derived) can be completely different 
than Rebindable(const Base). So are covariant return types even 
possible I wonder?

If D had implicit conversions then types can specifically say 
that they explicitly allow behavior like this where it made sense 
though.

>
> Speculation: There may be problems once we try to wrap class 
> references in two different structs. We might want Optional or 
> NonNull, and then another wrapper (e.g., Rebindable) for some 
> other benefit. When these wrappers are written with 
> if-constraints to take only raw D class references, we may pick 
> only one wrapper. But I haven't investigated this yet.
>
> -- Simon

Aye, I guess Optional and NonNull would have to know about each 
other to make the most out of them together. I've actually been 
tempted to put in a NonOptional type inside the optional package. 
But maybe NonNull would make more sense since we may just want 
this behavior for reference types. and NonOptional!int is kinda 
... well wtf is that :p

Cheers
- Ali




More information about the Digitalmars-d mailing list