The Artima Developer Community
Sponsored Link

Weblogs Forum
Implementing Implicit Behavioral Subtyping using Traits

35 replies on 3 pages. Most recent reply: Jan 23, 2006 5:30 PM by Max Lybbert

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 35 replies on 3 pages [ « | 1 2 3 ]
Max Lybbert

Posts: 314
Nickname: mlybbert
Registered: Apr, 2005

Re: My opinion of multiple inheritance Posted: Jan 20, 2006 10:38 AM
Reply to this message Reply
Advertisement
/* [Me] Traits do offer a decent fix for this issue: define a trait that offers a "get_data_x" function, and require that all types accessed through that trait get "data_x" from *somewhere* but don't worry about where. ...

[Cosic] I don’t agree. Consider this example (Java code with additional rename keyword) ...

Clean, simple, readable.
*/

I like this one too. Now I feel like a county fair judge with a big appetite but no idea if one recipe is better than anoter.

/* I'm arguing that inheritance of state (and/or implementation) should be optional. Not obligatory, not forbidden, but optional. It's easy to add that to MI.
*/

Yep, I like this, *too*.

/* [Me] But what if D.method() needs A.method() to do something new?

[Cosic] You must be using Java. This requirement is easily added to MI, and, in fact, C++ already offers it ...
*/

Actually, I was thinking C++, but I know it's available in Java.

Here's the hypothetical:

class A
{ int a;
  int aa;
public:
  virtual void method(XML_document &doc)
  { doc.add_element(a).add_element(aa);
  };
};
 
class B : public A
{ float b;
public:
  void method(XML_document &doc)
  { doc.add_element(b);
    A::method(doc);
  };
};
 
class C : public B
{ std::string c;
public:
  void method(XML_document &doc)
  { doc.add_element(c)
    B::method(doc);
  };
};
 
class D : public C
{ int d;
public:
  void method(XML_Document &doc)
  {/* For whatever reason, d must be placed between a and aa.  what should I do? */
  };
};

Max Lybbert

Posts: 314
Nickname: mlybbert
Registered: Apr, 2005

Re: My opinion of multiple inheritance Posted: Jan 20, 2006 10:43 AM
Reply to this message Reply
The problem I'm illustrating isn't an issue with *multiple* inheritance, it's just an issue with inheritance.

Kresimir Cosic

Posts: 34
Nickname: kreso1
Registered: Jan, 2006

Re: My opinion of multiple inheritance Posted: Jan 21, 2006 7:42 AM
Reply to this message Reply
To me it looks like the problem is not in inheritance, but in how interfaces are designed in your example.

Your example is something like: There is class Stack, but for some reason it has no push method. Now that Stack is useless. You can't claim that's fault of inheritance.

The easiest fix it to provide getters for a and aa in class A.

You might have something else in mind, where, for whatever reason, it is not advisable to add getters for a and aa. But there are many other solutions, depending on what exactly the problem is.

Max Lybbert

Posts: 314
Nickname: mlybbert
Registered: Apr, 2005

Re: My opinion of multiple inheritance Posted: Jan 23, 2006 9:49 AM
Reply to this message Reply
/* To me it looks like the problem is not in inheritance, but in how interfaces are designed in your example.
*/

Well, I have to admit that I haven't run into this in practice either, so I may be jumping at shadows.

IMO, the problem is that once I've asked a class higher up in the hierarchy to handle something, I lose control until that class hands it back to me. Generally this is good as it permits me to ignore getter/setter methods for all parent classes. But it also means that I have no way of interrupting the call chain until it's finished.

FWIW, I believe traits allow make changes to the call chain (by swapping out A with A2 for D only). Then again, as I said, I haven't actually needed to do this, I just believe I may one day need to.

/* The easiest fix it to provide getters for a and aa in class A.
*/

But then I can't let C handle C-specific issues, same for B, same for A (once I call C::method() I'm resigned to letting it call B::method() and A::method()). There's a maintenance issue. Then again, for this to crop up, I may be at the wrong level of abstraction.

Kresimir Cosic

Posts: 6
Nickname: kreso
Registered: Jan, 2006

Re: My opinion of multiple inheritance Posted: Jan 23, 2006 10:15 AM
Reply to this message Reply
> But then I can't let C handle C-specific issues, same for
> B, same for A (once I call C::method() I'm resigned to
> letting it call B::method() and A::method()). There's a
> maintenance issue. Then again, for this to crop up, I may
> be at the wrong level of abstraction.

Oh, now I understand what you mean... nice example. Well, I agree, MI can't do what you want. Question is can traits do it. I don't really know, it's a complex issue, and probably depends on specific trait implementation.

This is not a subtyping issue, but subclassing. From MI perspective, what you want to do is change implementation of 'method' in D by overriding, but you want to keep some of implementation. This can only be solved if designer of class A predicted your need and wrote:

class A
{ int a;
int aa;
public:
virtual void method(XML_document &doc)
{ default_method_impl(doc);
}
protected:
virtual default_method_impl(XML_document &doc)
{ doc.add_element(a).add_element(aa);
}
}
.. which enables you to override default_method_impl in class D.

This is a solution to your problem in MI world. But I dislike this solution because I don't like 'protected'. I have devised another mechanism that completely eliminates need for protected keyword. But again, the designer of class A must have predicted the need to inherit part of implementation.

I don't believe this is a serious issue with MI. You just can't say 'I want to inherit 3/4 of implementation'. It's either whole or none.

Max Lybbert

Posts: 314
Nickname: mlybbert
Registered: Apr, 2005

Re: My opinion of multiple inheritance Posted: Jan 23, 2006 5:30 PM
Reply to this message Reply
/* I don't believe this is a serious issue with MI. You just can't say 'I want to inherit 3/4 of implementation'. It's either whole or none.
*/

I have to admit that the example is somewhat contrived *and* that I've never had a set of requirements that mandated this. However, it was the first thing I thought of when I read up on traits. Rather, the *first* thing was contracts (especially post-condition checking), but that's because cdiggins put that in my head. The first thing I came up with myself was this.

Flat View: This topic has 35 replies on 3 pages [ « | 1  2  3 ]
Topic: Generics and Packages Previous Topic   Next Topic Topic: What if Constant Values were also valid Types?

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use