From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: a07f3367d7,5af5c381381ac5a7 X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news2.google.com!npeer03.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!spln!extra.newsguy.com!newsp.newsguy.com!drn From: Luis Espinal Newsgroups: comp.lang.ada Subject: Re: Ada requires too much typing! Date: 1 Jun 2010 14:30:54 -0700 Organization: NewsGuy - Unlimited Usenet $19.95 Message-ID: References: NNTP-Posting-Host: pc6d9c503bb8f79149f6f8a4526eae13cd962c7a341b39194.newsdawg.com User-Agent: Direct Read News 5.60 Xref: g2news2.google.com comp.lang.ada:12183 Date: 2010-06-01T14:30:54-07:00 List-Id: In article , Alex R. Mosteo says... > >Luis Espinal wrote: > >>(...) >> We have also come to learn that interfaces, the prohibition of multiple >> inheritance, (...) were not a good idea at all. > >Thanks for the elaborate reply. Not expert in Scala/Java so I can't comment >about most of it. > >However, seeing that Ada has just copied Java interfaces, I'd like to known >a bit more in detail why you say what I quoted, if you have the time. I have >used interfaces a bit and indeed have some grudges with them, but I'd like >to know if the situation is worse than I think -- or perhaps I'm not using >them 100% properly. > >Thanks in advance, > >Alex. Hi Alex - sorry I didn't reply sooner. I've been on the grind at work in the last couple of days. The issue with interfaces (which is not universally accepted among Java developers) is that they cannot be changed without incurring in changes to classes implementing that interface. This is a big issue for the way in which code is developed in Java. Let me try to illustrate: The common practice in Java is find a platform or framework (some sort of high-level "virtual" OS for lack of a better word.) Then, either write your apps on it, or develop another platform on top of it (another, more refined, more business-specific "virtual" OS. So pretty much we (try to) gradually refine the architecture of an application via an architecture pre-defined by the runtime below it. Examples of this are JEE, Spring and the Eclipse framework (and all the stuff + the kitchen sink that we throw on top of them.) All those layers are typically defined with interfaces (since we don't get multiple inheritance or mixin/traits). We end up with these long class hierarchies, and lots and lots of artifacts implementing lots and lots of interfaces. Libraries and libraries, and platforms and platforms... without a concept of versions. So for example, you have an interface named A that defines a method foo(): public interface A { public void foo(); } And then you have a large number of classes implementing A, which are distributed to 3rd parties. A while later, you find you must include a new method on interface A: public interface A { public void moo(); } The moment you do that, you render every library that depended on old A unusable. Either your clients won't be able to compile it, or if they will get nasty run-time errors. The JVM will even refuse to load the old classes because they do not conform with the new interface anymore. The folks in the eclipse framework, for example, have had to deal with this problem by implementing "versioned" interfaces and have code deal with them at run-time: public interface A { public void foo(); } public interface A_1 { public void moo(); } class clientOfA { void dooFooAndMaybeMoo( A someA ) { ... if( someA instanceof A_1 ) { ((A_1)someA).moo(); } ... } This could get out of hand (specially with sloppy programmers which, in Java, unfortunately we have too many.) This can also be a concern with people that develop frameworks and libraries for both external and internal use. So what we do is that, in addition to implementing an interface, we typically extend a an abstract base class that can insulate us from possible changes to the interface: public interface A {...} public abstract class AbstractA implements A {...} public class ConcreteA extends AbstractA {...} If we need to change A, we simply change AbstractA so that clients of A that extend AbstractA don't get forced to change their source... but that doesn't do anything for those that still extend A directly. And having an abstract base class like that defeats the purpose of being able of creating arbitrary implementations of an interface. Other folks deal with that problem by creating Adapters... ending up with a soup of design patterns going wild. Some people still think this is still a better trade-off over C++ styled multiple inheritance because of the dreaded "diamond" problem. To me (and this is strictly a personal opinion), it isn't. That's a lot of manual shamanism that should be better dealt with syntactically. We should have had multiple implementation inheritance from the get-go and just deal with it using the tools of the language and careful planning. I think the Scala guys had the most wonderful of ideas by implementing Traits. They offer many of the benefits of interfaces while simplifying the ability of inheriting multiple implementations. The focus is no longer on building behavior not just with inheritance but also with composition. I don't need to worry if my object is a-something to that can do a-task; I just have to worry that it can perform the task. I do think that interfaces have been great for specifying contracts. They enforce an order on things. However, it is important to plan ahead regarding interface versions. I don't know if this is a big deal in Ada-land, but in the JVM-land, it has been. Please take it with a grain of salt. It is simply my observation, and with software YMMV from one context to another :) - Luis Espinal (luis.espinal@gmail.com)