View mode: basic / threaded / horizontal-split · Log in · Help
March 28, 2007
Covariance fix (was: Idea: Lazy upcasting)
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/
-------------------------------------
March 29, 2007
Re: Covariance fix (was: Idea: Lazy upcasting)
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
April 01, 2007
Re: Covariance fix (was: Idea: Lazy upcasting)
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:
>
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/
-------------------------------------
Top | Discussion index | About this forum | D home