Idea: Lazy upcasting

Marcin Kuszczak aarti at interia.pl
Mon Mar 26 14:56:06 PDT 2007


Hello!

Recently I have tried to achieve chaining a few calls to setters. I mean
something like below:

//-------------------------------------------

abstract class Storage {
     Storage param1(int p1) {
         this.p1 = p1;
         return this;
     }
private:
     int p1;
}

class SpecificStorage : Storage {
public:
     SpecificStorage param2(bool p2) {
        this.p2=p2;
        return this;
     }
private:
     bool p2;
}

void main() {
//                             ...ok...      ...ok...        ...ups!
SpecificStorage1 s1 = (new SpecificStorage).param2(true).param1(5);
}

//-------------------------------------------

Because returned type from param1 is Storage above example doesn't work...

Unfortunately currently it is necessary to add overridden implementation of 
param1() in SpecificStorage:

     SpecificStorage param1(int p1) {
         this.p1 = p1;
         return this;
     }


But my intuition about that would be that "this" pointer from method param1 
will point to "SpecificStorage" when it is used in SpecificStorage. But it
is upcasted to Storage during return from param1.

Such a behavior seems a nonsense when there is covariance return type
feature in programming language. To get covariance I have to reimplement
same code in every inherited class just to trigger proper behaviour.

Here I would like to propose a change:

****
There should be no upcast during return. When function returns descendant of
declared type it should not be converted to base class (declared) but
function should return descendant type. I think about this as a lazy
upcasting :-)
****

It should not break anything when instead of making upcasting during return
compiler just return concreate type and probably later make upcast when
e.g. assigning to Storage variable. When I want to assure that Storage
class will be returned I just can add cast in base class like below:

Storage param1(int p1) {
        this.p1 = p1;
        return cast(Storage)this;
}

But usually there is a need to get opposite behaviour and get descendant
class not ancestor...

-----

I would say that recently, when new dmd 1.010 appeard, such a change should
additionally improve language. There is a new method in Object:

static Object factory(char[]);

It will be usually used to create specific classes, not Object class so
usage will be like below:
SpecificStorage s = cast(SpecificStorage) Object.factory("SpecificStorage");

With proposed change you will just get:
SpecificStorage s = Object.factory("SpecificStorage");

Advantages:
- downcasts are no more necessary (there are no casts at all, although it
could look like there are implicit downcasts)
- no need for reimplementation of same method returning this in derived
classes just to get covariance work
- coherent with covariance feature

I don't know disadvantages, so I would like to hear your opinion. Maybe it
is just technically difficult, but I don't know dmd compiler good enough to
say that... 

Anyway please comment on that...

-- 
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/
-------------------------------------




More information about the Digitalmars-d mailing list