Gravatar

Generic solution for inheritance?

Given two classes:

class d {
  int a;
  int b(int c) {
    a=c;
  }
  void create() {
  }
}

class e {
  inherit d;

  int f;
  void create() {
    ::create();
  }
  int g(int h) {
    f=h;
  }
}

e getnew() {
  d k=d();
  e m=k;	  // doesn't work, will force the object to be of class d
  return m;
}

Now, without knowing the complexity and/or content of class d and
(Continue reading)

Arne Goedeke | 21 Aug 09:10

Re: Generic solution for inheritance?

It would be possible to implement some class that wraps around
d and e. It would overload `->() and `[] and store both objects 
to make the actual lookups.

bless(object a, program b);

Truth is, we are missing perl ;-).

Still is doesnt seem too hard to implement Stdio.File()->assign() 
generically. Simply iterate all object variables and try to
assign them to the new object. Only problem is that you cannot replace
all the references to the old object easily.

arne

On Thu, 21 Aug 2008, Stephen R. van den Berg wrote:

> Given two classes:
>
> class d {
>  int a;
>  int b(int c) {
>    a=c;
>  }
>  void create() {
>  }
> }
>
> class e {
>  inherit d;
(Continue reading)

Gravatar

Re: Generic solution for inheritance?

Arne Goedeke wrote:
>It would be possible to implement some class that wraps around
>d and e. It would overload `->() and `[] and store both objects 
>to make the actual lookups.

That is uglier than I intended, actually.

>bless(object a, program b);
>Truth is, we are missing perl ;-).

I presume that is the Perl syntax for the desired feature?

>Still is doesnt seem too hard to implement Stdio.File()->assign() 
>generically. Simply iterate all object variables and try to
>assign them to the new object. Only problem is that you cannot replace
>all the references to the old object easily.

That I don't care about.  I.e. the only thing that counts is that I can
pass on the new reference to anyone and it will work transparently.
In practice I'm intercepting right after object creation somewhere and
therefore *know* that there are no (other) external references to this object,
except this one instance that I'm holding now.

The only other references to the old object could be internal ones
(internal to the object).  Not sure if those could be trouble; if yes,
then maybe they can be altered, or this functionality will be restricted
to objects with one ref only.
--

-- 
Sincerely,
           Stephen R. van den Berg.
(Continue reading)

Arne Goedeke | 21 Aug 13:18

Re: Generic solution for inheritance?


On Thu, 21 Aug 2008, Stephen R. van den Berg wrote:

> Arne Goedeke wrote:
>> It would be possible to implement some class that wraps around
>> d and e. It would overload `->() and `[] and store both objects
>> to make the actual lookups.
>
> That is uglier than I intended, actually.
true.

>> bless(object a, program b);
>> Truth is, we are missing perl ;-).
>
> I presume that is the Perl syntax for the desired feature?

object creation in perl is done using the bless funcall. the difference
however is, that in perl you are blessing arbitrary references. and you
may change the class of a reference as often as you like using bless.

I recall that on the last pike conference there was some discussion about
whether or not it would be good to add support for arbitrary Stdio.File
subclasses to Stdio.Port()->accept() and the like. I think in general
thats the way to go, especially because you cannot access all object
variables from pike (take the string_builder struct in String.Buffer
for instance) and copy them around.

arne

(Continue reading)

Martin Stjernholm | 22 Aug 04:35
Favicon

Re: Generic solution for inheritance?

"Stephen R. van den Berg" <srb <at> cuci.nl> wrote:

> Now, without knowing the complexity and/or content of class d and
> without altering the content of class d, is it possible to construct the
> class e and the function getnew() in such a way that the function getnew is
> able to return a real class e object?

If I understand you correctly, you want e to wrap a d instance
(through a variable reference), and then you want to inherit a wrapper
class constructed from d. This wrapper class contains all identifiers
from d but they only act as proxies to the real things in the internal
d instance (this is what Fd_ref is to Fd).

There is no builtin functionality for that. I agree it could be useful
every once in a while.

But if d is likely to be used that way, a better way is to construct d
with it in mind. I.e. add a method to it (preferably create()) to let
one d instance take over all the state of another (possibly consuming
and destructing the original if required). Then you can inherit a real
d and let it take over the other d instance you have when the e object
is created. That way the wrapper calls are avoided.

Martin Bähr | 22 Aug 05:18

Re: Generic solution for inheritance?

On Fri, Aug 22, 2008 at 09:35:40AM +0700, Martin Stjernholm wrote:
> But if d is likely to be used that way, a better way is to construct d
> with it in mind.

well, theproblem is usually that you are not able to change d it self
but you need to add functionality (which you can with subclassing) but
then you still have original objects that you can't change.

if there were a chance to construct d, then you could add the
functionality to it directly and you would not even have to bother
with subclassing or a wrapper.

what would be nice is to cast from a parent class to a subclass without
the need of a cast() function in the parent class.
we know that the subclass is compatible so casting should be possible
without extra information.

greetings, martin.
--

-- 
cooperative communication with sTeam      -     caudium, pike, roxen and unix
offering: programming, training and administration   -  anywhere in the world
--
pike programmer   working in china                      community.gotpike.org
unix system-      iaeste.(tuwien.ac|or).at                     open-steam.org
administrator     caudium.org                                    is.schon.org
Martin Bähr       http://www.iaeste.or.at/~mbaehr/

Martin Stjernholm | 24 Aug 18:16
Favicon

Re: Generic solution for inheritance?

Martin Bähr <mbaehr <at> email.archlab.tuwien.ac.at> wrote:

> well, theproblem is usually that you are not able to change d it self
> but you need to add functionality (which you can with subclassing) but
> then you still have original objects that you can't change.

Yes, that can be the case. I only mentioned changing d as a better
alternative if we have some control over that class.

> if there were a chance to construct d, then you could add the
> functionality to it directly and you would not even have to bother
> with subclassing or a wrapper.

Not really. If d is part of Pike then it might very well be doable to
add something like Stdio.File.assign to it, while adding your own
subclassed variant to Pike isn't an option.

> what would be nice is to cast from a parent class to a subclass without
> the need of a cast() function in the parent class.
> we know that the subclass is compatible so casting should be possible
> without extra information.

I don't understand. As I read Stephen's case, the subclass e would add
functionality, so only type casting d to e doesn't work. (If it only
came to that, it's not hard to fool Pike to put an instance of d into
a variable with the type e.) And if d is to be value casted to an e
instance then we're back to the original problem as to how that value
cast can be carried out.

(Continue reading)

Martin Bähr | 24 Aug 19:37

Re: Generic solution for inheritance?

On Sun, Aug 24, 2008 at 11:16:41PM +0700, Martin Stjernholm wrote:
> > what would be nice is to cast from a parent class to a subclass without
> > the need of a cast() function in the parent class.
> > we know that the subclass is compatible so casting should be possible
> > without extra information.
> if d is to be value casted to an e instance then we're back to the
> original problem as to how that value cast can be carried out.

that is exactly the issue i was addressing.
currently such a cast is not possible. 
however, i am suggesting that pikes casting support could be extended to
cover such a case and cast from a parent class to a subclass without the
parent class needing to provide a cast() function.

in other words, such a cast would imply the existance of a cast function
which copies all the data from the object of parent class to the object
of the child class. this copying should be straight forward because we
know that the parent class is compatible with the child.

class P
{
  string name;
  create(int _name){ name = _name; }
}

class C
{
  inherit P;
  void hello(){ write("hello my name is %s", name); }
}
(Continue reading)

Henrik Grubbström | 24 Aug 19:58
Favicon

Re: Generic solution for inheritance?

On Sun, 24 Aug 2008, Martin Bähr wrote:

> On Sun, Aug 24, 2008 at 11:16:41PM +0700, Martin Stjernholm wrote:
>>> what would be nice is to cast from a parent class to a subclass without
>>> the need of a cast() function in the parent class.
>>> we know that the subclass is compatible so casting should be possible
>>> without extra information.

Actually you don't, see below.

>> if d is to be value casted to an e instance then we're back to the
>> original problem as to how that value cast can be carried out.
>
> that is exactly the issue i was addressing.
> currently such a cast is not possible.
> however, i am suggesting that pikes casting support could be extended to
> cover such a case and cast from a parent class to a subclass without the
> parent class needing to provide a cast() function.
>
> in other words, such a cast would imply the existance of a cast function
> which copies all the data from the object of parent class to the object
> of the child class. this copying should be straight forward because we
> know that the parent class is compatible with the child.
[...]
> pike does not need any special knowledge about casting from P to C
> because all it needs to do is copy the value in name.
>
> or am i missing something?

You're missing several things:
(Continue reading)

Martin Bähr | 24 Aug 20:19

Re: Generic solution for inheritance?

On Sun, Aug 24, 2008 at 07:58:30PM +0200, Henrik Grubbström wrote:
>   * Pike's typesystem is based on the looks-like relation, there's thus no
>     no way to know exactly what implementation of the api P is used to
>     implement person.

object_program() does not help here?

>   * (Related to the above) symbols that are declared protected (fka
>     static) or private are not part of the type signature. Should such
>     variables be copied?

they could be copied into the parent namespace of the target.
iaw: a new object of C is created, which contains a version of P that
matches the current state of the instance of P that is being casted.

>     What if the object being casted contains symbols
>     that conflict with symbols in the type being casted to?

if the type being casted to inherits the type being casted from, how can
there be any conflict?

>   * C might extend P with variables; what values should they be assigned
>     with?

the same values that they would get if a fresh instance of C is created.
ok, this would fail if C has a create() function that requires some
arguments. it is also not clear what the create() function would do if
inherited valiables have different values than expected.

maybe a cast_from() function would help here to indicate if a class is
(Continue reading)

Gravatar

Re: Generic solution for inheritance?

>>>> what would be nice is to cast from a parent class to a subclass  
>>>> without
>>>> the need of a cast() function in the parent class.
>>>> we know that the subclass is compatible so casting should be  
>>>> possible
>>>> without extra information.

Why on earth would you want to do that? You shouldn't be able to cast  
to a subtype unless the object was created as that subtype (or is  
within the class hierarchy between the base class and the type the  
object was created as) to begin with. Otherwise, you'd end up with  
situations like:

Animal a = Animal("tony tiger");

Bird b = (Bird)a; // tony tiger is not a bird.

Or am I missing something? It sounds like what you're really hoping  
for is more things in Pike to use the Factory pattern, where you can  
specify the specific class an object is created as dynamically.

Bill

Martin Baehr | 24 Aug 21:19

Re: Generic solution for inheritance?

On Sun, Aug 24, 2008 at 02:58:10PM -0400, H. William Welliver III wrote:
> Animal a = Animal("tony tiger");
> Bird b = (Bird)a; // tony tiger is not a bird.

what's wrong with that?
there is nothing that makes a be a tiger other than the name.
a is an animal. after the cast, b is still an animal (asuming that Bird
inherits Animal). so where is the problem?

see also: http://en.wikipedia.org/wiki/Tigerente

greetings, martin.
--

-- 
cooperative communication with sTeam      -     caudium, pike, roxen and unix
offering: programming, training and administration   -  anywhere in the world
--
pike programmer   working in china                      community.gotpike.org
unix system-      iaeste.(tuwien.ac|or).at                     open-steam.org
administrator     caudium.org                                    is.schon.org
Martin Bähr       http://www.iaeste.or.at/~mbaehr/


Gmane