www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Covariance fix (was: Idea: Lazy upcasting)

reply Marcin Kuszczak <aarti interia.pl> writes:
Hello!

Any chance to get Walter interested with this? It seems that he has head so
full of macros and constness that so small improvements will not easily
catch him :-)

But anyway, I will try <g>

******************************************************
Subject: 
---
Proposition of fixing covariance design in D

Current problems: 
---
1. It is necessary to make "copy & paste" implementation for base functions
in derived classes just to return different (covariant) type from overriden
method
2. Syntax is quite unintuitive: In base class you declare method with
signature containing Base class name, but in derived classes you need to
use in signature inherited class name.

Proposed solution:
---
class Base {
        this foo(int i) { return this; } // function declared as returning
"this" 
                                         // in base class
        this other() { return this; }    // same as above
}
 
class Derived : Base {
        this foo(int i) { return this; } // function overriding base class 
                                         // returns Derived
        this bar(int i) { return this; } // another function which will return 
                                         // Derived

        Base foo1() {} // foo1 returns always Base class instance
        Derived bar() {} // always returns Derived
        // in derived class method 'other' from base class is also 
        // available. It returns Derived.
}
 
void main() {
        Derived d = (new Derived).foo(1).bar(2).other; // no problem here
}
 
 
Return type 'this' should be just another special return type, like 'void'
type is currently. This special type shows precisely what will be returned
from function. It is possible to say exactly what return type will be just
seeing method (in class) declaration. It's consistent and looks good. It's
also probably even easier to work with it for compiler.
 
Advantages:
---
1. No problem with loosing information about class type. Currently it is
lost due to implicit upcasting from derived classes to base classes.
2. No need to reimplement same function just to get different return type.
3. Clean syntax. You have same signature in base, and in derived classes.
4. Possibility to extend syntax also for method parameters and class
members.

Use cases:
---
1. Chaining of method calls from different base and derived classes.
2. All interfaces to classes which should return itself - problem for
library classes which can be overriden by user.

Counter propositions:
---
1. Use template mixins to insert implementation into derived classes
(requires from user of library to remember to mix in parameters to derived
class)
2. Using template magic to achieve proper behaviour (neither easy nor
intuitive; requires from user of library to use and understand quite
advanced subjects). Examples in original thread.

References:
---
1. Thread:
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=51201

******************************************************

BTW - some officially blessed by Walter system for tracking enhancement
requests would be great (bugzilla has its own problems with this, as it was
already mentioned before on NG).

-- 
Regards
Marcin Kuszczak (Aarti_pl)
-------------------------------------
Ask me why I believe in Jesus - http://zapytaj.dlajezusa.pl (en/pl)
Doost (port of few Boost libraries) - http://www.dsource.org/projects/doost/
-------------------------------------
Mar 28 2007
next sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Marcin Kuszczak wrote:
 Hello!
 
 Any chance to get Walter interested with this? It seems that he has head so
 full of macros and constness that so small improvements will not easily
 catch him :-)
 
 But anyway, I will try <g>

I haven't really looked to closely at your argument, but it seems there may be a more general principle at work here. It seems like what you want is a way to have 'identity' return values. This seems to me very related to Andrei's "Challenge #1" posted a while back which was basically to write a function/template that returns its argument exactly with all relevant type modifiers. In your example you are seeking to do that for one special argument, the implicit 'this' argument. class Base { this foo(int i) { return this; } this other() { return this; } } But maybe it would be more useful to consider a way to label any parameter of any function as having an identity return value. For instance something like: identity(Bar) foo(Bar x, int i) { return x; // returns with the exact type of x // that was passed in which could be a // subclass of Bar } In Luigi (http://www.dsource.org/projects/luigi) I have a templated method that I use for that purpose. It returns it's argument exactly, which allows one to do things like: Button b = parent.add(new Button(), add_option1, add_option2); The 'add' method returns the exact type of its argument. I think the concept is interesting, but my gut tells me that if you want something like that it's got to be done as a template. If you don't like the way the template works, then your proposal should be to change how templates work, not to add some new 'this' return value syntax. --bb
Mar 28 2007
prev sibling parent Marcin Kuszczak <aarti interia.pl> writes:
Recently I have found that proposed solution is already almost implemented
in D. It is possible to use 

typeof(this) 

in definition of return type of function. The only problem with it is that
when instantiating derived class, 'this' points to base class **NOT** to
derived class, so that type of function is still pointing to base class
although it should point to derived class. I think it is quite unlogical
and unintuitive (in instance of derived class this points to derived
class). Fixing it would decrease number of unnecessary casts.

I hope it could be fixed.

Best Regards
Marcin Kuszczak
(aarti_pl)

/*************************************************************************/

Marcin Kuszczak wrote:

 Hello!
 
 Any chance to get Walter interested with this? It seems that he has head
 so full of macros and constness that so small improvements will not easily
 catch him :-)
 
 But anyway, I will try <g>
 
 ******************************************************
 Subject:
 ---
 Proposition of fixing covariance design in D
 
 Current problems:
 ---
 1. It is necessary to make "copy & paste" implementation for base
 functions in derived classes just to return different (covariant) type
 from overriden method
 2. Syntax is quite unintuitive: In base class you declare method with
 signature containing Base class name, but in derived classes you need to
 use in signature inherited class name.
 
 Proposed solution:
 ---
 class Base {
         this foo(int i) { return this; } // function declared as returning
         "this"
                                          // in base class
         this other() { return this; }    // same as above
 }
  
 class Derived : Base {
         this foo(int i) { return this; } // function overriding base class
                                          // returns Derived
         this bar(int i) { return this; } // another function which will
         return
                                          // Derived
 
         Base foo1() {} // foo1 returns always Base class instance
         Derived bar() {} // always returns Derived
         // in derived class method 'other' from base class is also
         // available. It returns Derived.
 }
  
 void main() {
         Derived d = (new Derived).foo(1).bar(2).other; // no problem here
 }
  
  
 Return type 'this' should be just another special return type, like 'void'
 type is currently. This special type shows precisely what will be returned
 from function. It is possible to say exactly what return type will be just
 seeing method (in class) declaration. It's consistent and looks good. It's
 also probably even easier to work with it for compiler.
  
 Advantages:
 ---
 1. No problem with loosing information about class type. Currently it is
 lost due to implicit upcasting from derived classes to base classes.
 2. No need to reimplement same function just to get different return type.
 3. Clean syntax. You have same signature in base, and in derived classes.
 4. Possibility to extend syntax also for method parameters and class
 members.
 
 Use cases:
 ---
 1. Chaining of method calls from different base and derived classes.
 2. All interfaces to classes which should return itself - problem for
 library classes which can be overriden by user.
 
 Counter propositions:
 ---
 1. Use template mixins to insert implementation into derived classes
 (requires from user of library to remember to mix in parameters to derived
 class)
 2. Using template magic to achieve proper behaviour (neither easy nor
 intuitive; requires from user of library to use and understand quite
 advanced subjects). Examples in original thread.
 
 References:
 ---
 1. Thread:

 
 ******************************************************
 
 BTW - some officially blessed by Walter system for tracking enhancement
 requests would be great (bugzilla has its own problems with this, as it
 was already mentioned before on NG).
 

-- Regards Marcin Kuszczak (Aarti_pl) ------------------------------------- Ask me why I believe in Jesus - http://zapytaj.dlajezusa.pl (en/pl) Doost (port of few Boost libraries) - http://www.dsource.org/projects/doost/ -------------------------------------
Apr 01 2007