www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 2295] New: automatically covariant types

reply d-bugmail puremagic.com writes:
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.


-- 
Aug 19 2008
next sibling parent d-bugmail puremagic.com writes:
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.


-- 
Aug 19 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
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.


-- 
Aug 19 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
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"


-- 
Aug 19 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
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.


-- 
Aug 19 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
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


-- 
Aug 20 2008
prev sibling parent d-bugmail puremagic.com writes:
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 ***


-- 
Aug 20 2008