Opt-in non-null class references?

SimonN eiderdaus at gmail.com
Thu Mar 15 05:04:25 UTC 2018


On Sunday, 11 March 2018 at 09:28:39 UTC, aliak wrote:
> Does this maybe boil down to if two templates should be 
> covariant on their parameter types?

I'm not sure if this is always good. I haven't thought about it 
deeply, but I assume that some templated functions should be 
contravariant, and that there is no catch-all rule.

> inference, in theory Rebindable!(const Derived) can be 
> completely different than Rebindable(const Base). So are 
> covariant return types even possible I wonder?

I don't think covariant return types will work here with the 
2018-03 language spec. We're returning structs 
(Rebindable!Something) and covariant return types is specifically 
for classes. :-)

It's one of the reasons why I shun wrapping types unless the 
benefit is really big.

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

Yeah -- it shifts another burden of implementation to library 
type authors, I'm not sure if this path should be followed, 
especially since implicit constructor calls are shunned in D. (I 
have no opinion whether C++'s implicit constructor calls are 
handy enough for the obscured program flow.)

* * *

Here's another example where wrapped class references fail: You 
can override opEquals in the class, and the struct's opEquals 
need not necessarily call that.

     import std.stdio;
     import std.typecons;

     class C {
         int x;
         override bool opEquals(Object rhsObj)
         {
             const(C) rhs = cast(const(C)) rhsObj;
             return this.x == rhs.x;
         }
     }

     void main()
     {
         C a = new C();
         C b = new C();
         assert (a == b); // OK: Even though a !is b, we overrode 
opEquals
                          // and compare a.x == b.x, which is true 
(0 == 0).

         Rebindable!(const(C)) ca = a;
         Rebindable!(const(C)) cb = b;
         assert (ca == cb); // Fails! struct Rebindable doesn't 
forward its
                            // opEquals to the class's opEquals!
     }

If this is by design, then it's very surprising. I've reported 
this as a bug to get a judgement from the Phobos authors: 
https://issues.dlang.org/show_bug.cgi?id=18615

-- Simon


More information about the Digitalmars-d mailing list