Thread overview
[Issue 2295] New: automatically covariant types
Aug 19, 2008
d-bugmail
Aug 19, 2008
d-bugmail
Aug 19, 2008
d-bugmail
Aug 19, 2008
d-bugmail
Aug 19, 2008
d-bugmail
Aug 20, 2008
d-bugmail
Aug 20, 2008
d-bugmail
August 19, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2295

           Summary: automatically covariant types
           Product: D
           Version: unspecified
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: fawzi@gmx.ch


given
{{{
class A{
  A methodA(){
   return this;
  }
}

class B:A{
  B methodB(){
   return this;
  }
}
}}}

call chaining

{{{
B b=new B();
 b.methodA().methodB();
}}}

does not work (also for opCall).

one can make it work by redefining methodA in B, with a call to super and a
cast (or return this).

This use is common enough that hacks to achieve it have been written (autoOverride in http://team0xf.com:8080/utils/file/9f4c03931278/Meta.d )

Actually if one returns this, one can safely do it for each subclass, and is widespread enough I think to warrant some language support.

What I would like is to write
{{{
class A{
  This methodA(){
   return this;
  }
}
}}}
or
{{{
class A{
  typeof(this) methodA(){
   return this;
  }
}
}}}
and have the compiler automatically adapt the return type to the actual
(compiletime known) subclass.

It would be equivalent to write
{{{
  typeof(this) methodA(){ super.methodA(); return this; }
}}}
or
{{{
  typeof(this) methodA(){ return cast(typof(this))super.methodA(); }
}}}
or even
{{{
  typeof(this) methodA(){ union T{typeof(super) s,typeof(this) t}; T
t.s=super.methodA(); return t.t; }
}}}
in each subclass.

The last two methods would allow one to return also null instead of this.


-- 

August 19, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2295





------- Comment #1 from shro8822@vandals.uidaho.edu  2008-08-19 14:36 -------
That first bit is (and IMHO should be) invalid

{{{
B b=new B();
 b.methodA().methodB();
}}}

typeof(b.methodA()) == A
A has no .methodB

If you want the implied semantics I think there should be a substantially different syntax.

The solution I would like to see would be an "automatically instanced template" or "automatic mixin". This would be a (parameterless) template that is automatically mixed into the given class and any derived class. This would let you define methodA to have a return type of typeof(this) getting the hoped for result. I have though of other cool thing to do with such a feature but, ATM, I don't remember what.


-- 

August 19, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2295





------- Comment #2 from fawzi@gmx.ch  2008-08-19 17:00 -------
I think that almost the only reason a method returns always this is to allow call chaining and replace

 a.f; a.g; a.h;

with

 a.f.g.h;

if you have a class B:A then you cannot mix B methods with a methods using call chaining.

it would be perfectly safe to have

  typeof(b.methodA())==B

if methodA returns this for the purpose of call chaining.

Call chaining is quite likely to be used for streams, serializers and similar, and having the subclasses to have to wrap all the interface is not nice to be able to use an extended set of chainable methods.

An automatic subclass mixin could also be a solution (and it would also allow automatic decoration of other methods in the subclass), but also more dangerous... a solution only for this problem which I think is common enough would be ok for me, the problem is I think common enough to warrant it.


-- 

August 19, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2295





------- Comment #3 from shro8822@vandals.uidaho.edu  2008-08-19 18:25 -------

based on that, you might as well allow this:

class A
{
  this Boo(){return;} // this return type always returns this
}
class B{}
auto b = (new B).Boo; // type is B value is "this"


-- 

August 19, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2295





------- Comment #4 from andrei@metalanguage.com  2008-08-19 18:33 -------
Other possible uses are to express a clone function (returns the same type as
the leaf type) and comparison (accepts only the same type as the leaf type).

There was a name for this idiom in Eiffel, I think, but I forgot it.


-- 

August 20, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2295





------- Comment #5 from aarti@interia.pl  2008-08-20 02:14 -------
Idiom's name is "anchored types".

It seems that this bug is duplicate of #1835:

http://d.puremagic.com/issues/show_bug.cgi?id=1835


-- 

August 20, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2295


matti.niemenmaa+dbugzilla@iki.fi changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
  BugsThisDependsOn|1835                        |
             Status|NEW                         |RESOLVED
         Resolution|                            |DUPLICATE




------- Comment #6 from matti.niemenmaa+dbugzilla@iki.fi  2008-08-20 08:15 -------
It is indeed a duplicate of 1835.

*** This bug has been marked as a duplicate of 1835 ***


--