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.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: fac41,953e1a6689d791f6 X-Google-Attributes: gidfac41,public X-Google-Thread: 103376,953e1a6689d791f6 X-Google-Attributes: gid103376,public From: eachus@spectre.mitre.org (Robert I. Eachus) Subject: Re: Eiffel and Java + Ada dispatching Date: 1996/10/30 Message-ID: #1/1 X-Deja-AN: 193422713 references: <550sm2$sn1@buggy.news.easynet.net> organization: The Mitre Corp., Bedford, MA. newsgroups: comp.lang.eiffel,comp.lang.ada Date: 1996-10-30T00:00:00+00:00 List-Id: In article <557ce3$ojh@tjnews.is.s.u-tokyo.ac.jp> jezequel@piccolo.is.s.u-tokyo.ac.jp (Jean-Marc Jezequel) writes: > The only thing you really need to make use of OO polymorphism is > dynamic binding. While having at the same time static overloading > can make some code fragment more "natural" to write, the apparent > proximity of this feature with dynamic binding yield so much > confusion on the non-expert eyes that you do not wonder why I > prefer to teach Eiffel rather than C++, Java or even Ada95. But you just teach it like we have always taught Ada overloading--if the compiler is happy you don't have a problem. ;-) Seriously the combination of dispatching on multiple parameters in Ada and overloading allows some really neat stuff--but the "simple" examples are so nasty I'm not going to write them, lest someone copy without understanding. Basically if a subprogram has multiple parameters which it dispatches on, and this can include the return value, and there is one and only one way to interpret the expression containing the call, then the dispatching resolves to a single controlling type. If you want the effect of dispatching on multiple parameters, and this is sometimes useful, you have to break the symmetry in your declarations: function "+"(L: Object; R: Object'CLASS) return Object'CLASS; will dispatch only on the first parameter, and you may have a second dispatching call to complete the dispatch. (It is the nature of these completing calls that they should be declared as generics immediately in the scope containing the type declaration, and instantiated elsewhere if they need both parameters.) Yes, you can end up doing N**2 or even N**3 instantiations if the implementation of the operation requires it. But that is still a win, since you would have had to write the individual operations anyway, but the generic can do part of the work. The other case, which is much more useful is where you can use a single intermediate type. Now you end up with at most 2N or 3N functions to write, and often using inheritance to eliminate most of those. For example suppose you have a tagged type, and you want to define heterogenous list type over the class. No problem, and no generics or additional declarations required, including for the operation: function "+"(L: Element, R: Element'CLASS) return Element_List; The body is: function "+"(L: Element, R: Element'CLASS) return Element_List is begin return L+New_List(R); end "+"; This body has two dispatching operations. New_List dispatches on R, and the + dispatches to the + defined for L's type and List. No overriding or additional declarations required, since the List type acts as an intermediate. (You can do the same thing with method notation, but it is a lot harder to get right. Try it. ;-) -- Robert I. Eachus with Standard_Disclaimer; use Standard_Disclaimer; function Message (Text: in Clever_Ideas) return Better_Ideas is...