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=unavailable autolearn_force=no version=3.4.4 Path: border2.nntp.dca.giganews.com!nntp.giganews.com!newspeer1.nac.net!feeder.erje.net!eu.feeder.erje.net!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Niklas Holsti Newsgroups: comp.lang.ada Subject: Re: Your wish list for Ada 202X Date: Sun, 13 Apr 2014 22:43:47 +0300 Organization: Tidorum Ltd Message-ID: References: <7f1c01c5-3563-4b94-9831-152dbbf2ecdc@googlegroups.com> <8bhozh836pyt$.1qctlysud0s2q$.dlg@40tude.net> <1cdsyxjzsfgzm.1synpaujysv21$.dlg@40tude.net> <1aa804jg9qq4o$.wdiq33yo621l.dlg@40tude.net> <1w6eh0aiksmdh$.1h16p7y0b8c6h.dlg@40tude.net> <17twpp4p8u7o$.1idvzaaio4f3t$.dlg@40tude.net> <1wjmcbk375lzk.6o7dpqcp3va3.dlg@40tude.net> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Trace: individual.net hSXd3k4nap1xCPG3RWvNtw568LQkI2N1D/dgp/5MF3+5m/O8q4 Cancel-Lock: sha1:mBQ+gqavKSEvaY294APvMhm/cf4= User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Thunderbird/24.4.0 In-Reply-To: <1wjmcbk375lzk.6o7dpqcp3va3.dlg@40tude.net> Xref: number.nntp.dca.giganews.com comp.lang.ada:185729 Date: 2014-04-13T22:43:47+03:00 List-Id: On 14-04-12 11:20 , Dmitry A. Kazakov wrote: > On Sat, 12 Apr 2014 00:04:48 +0200, Niklas Holsti wrote: > >> On 14-04-11 22:43 , Dmitry A. Kazakov wrote: >>> On Fri, 11 Apr 2014 21:04:58 +0200, Niklas Holsti wrote: >>> >>>> On 14-04-10 17:31 , Dmitry A. Kazakov wrote: >>>>> On Wed, 9 Apr 2014 22:28:36 -0500, Randy Brukardt wrote: >>>> >>>> [snip] >>>> >>>>>> We don't want "type-specific" implementations of most things -- that's just >>>>>> adding a maintenance headache where one isn't needed. >>>>> >>>>> It is need for >>>>> >>>>> 1. safety (because you statically know that certain specific operation may >>>>> not fail, while class-wide operations can) >>>>> >>>>> 2. efficiency >>>>> >>>>> There is no maintenance overhead whatsoever. Here is the proof. Let you can >>>>> provide a generic implementation (as you suggested), then this >>>>> implementation can be safely inherited. >>>> >>>> If you change a class-wide operation to an inherited (i.e. primitive) >>>> operation, you have to change its dispatching calls to redispatching >>>> calls, if you want the same behaviour as for the class-wide operation. >>> >>> No. I meant that the behavior of class-wide operation was defined = there >>> were no re-dispatch to operations that could be overridden to some >>> unanticipated behavior. >> >> You mean that a class-wide operation should not call any primitive >> operations of its parameters? > > They should, that was not the point. Which was maintainability. A > class-wide operation cannot be more maintainable than a primitive > operation. At least, it would require the level of contract thoroughness > Ada presently does not possess, not even close. > >>> Regarding use cases where re-dispatch comes in question, which certainly >>> exist, >> >> Ah, that is comforting. I thought you were totally against redispatch. > > Yes I am. Re-dispatch is a flawed solution to a real problem. Oh. Then I'm not comforted after all. > I don't deny > existence of the problem. I am against the solution, which is inherently > unsafe and constraining (precludes by-copy semantics). But class-wide operations which contain dispatching calls also preclude by-copy semantics, don't they? Unless you consider a class-wide type as similar to an access type, and pass a reference (pointer) by copy. Which would be a silly meaning of "by-copy". A class-wide operation, in my view, is just like a primitive operation except that (1) (re-)dispatching is implicit and automatic for all calls to primitive operations of the parameter object (because the parameter is a class-wide type) and (2) the operation cannot be overridden. Because of (2) I don't often use class-wide operations, but instead make the operation primitive for the root type and use re-dispatching. (This is why I don't understand your and Randy's abhorrence of re-dispatching -- to me, there is no basic difference between dispatching calls in class-wide operations, and re-dispatching calls in primitive operations.) >>> I think that from the safety and maintenance point of view, the type >>> system should provide means of body composition beyond simple inherit vs. >>> override. >> >> That is certainly an interesting issue. You are thinking of something of >> the same kind as the "inner" of Simula? > > Yes, but it looks too low-level and hackish to me. I agree, for the "inner" thing itself. Some language constructs in the same area (composition of bodies along the inheritance axis) could be useful, but I don't now see the problems to be solved by these constructs, because re-dispatching works well enough for me. > The concept should somehow play together with the notion of polymorphic > operation defined on the class (set of types). Between these two ends: > independent bodies of a primitive operation and single body of a class-wide > operation, there lies a whole spectrum of unexplored possibilities. I feel that my use of re-dispatching gives me something like that. And I don't see the problems in re-dispatching that you and Randy worry about. >> In my own code, the primitive operations of a type are typically layered >> into levels: higher-level operations and lower-level ones. An overriding >> higher-level primitive operation is typically implemented by calling >> (with redispatch) lower-level primitive operations of the parameter >> object. The *same* (i.e. overridden) operation of the parent type is >> usually not called, nor does a primitive operation of a parent type call >> the same primitive operation from the actual derived type; only >> operations from lower layers are called. > > Yes, this is the way I implement it too. The difference is that I try to > keep "higher-level" operations class-wide. I have a few class-wide ops, but not many. They are for sure the higher-level, if not highest-level ops. > Then I try to maintain the "no > abstraction inversion" rule, i.e. never call a "higher-level" operation > from a "lower-level" one. Yes, same here. > Note that when "higher-level" operations are made class-wide, there is also > a formalized separation of two, as they act on different types. I think I have some classes with more than two levels of operations, so this separation would not work fully there. >>> We know, for example, that constructors (initialize) and >>> destructors (finalize) require other means of composition. More elaborated >>> composition tools should eliminate re-dispatch (and most class-wide >>> operations) => give safety and maintainability. >> >> Maybe... suggest something and we'll see. > > It is useless to suggest anything, as you know. Suggestions have to be very well motivated, as befits Ada's goals of long-term stability and portability. > And, I am not a language > designer anyway. I am a programmer. As a programmer, from my experience > with Ada, I tell the language designers that they got it all wrong since > Ada 2005. I don't want yet another dynamically typed or functional > language. I need a language for software engineering. More static checks, > more means to make static checks possible. The whole language should > revolute around helping restructuring my programs in order to support > static checks. No Constraint_Error to me, please! That's a good goal, but I don't think it should be the only goal for Ada. Ada's problem and challenge is that it very ambitiously aims to combine high-level, expressive, and therefore somewhat dynamic language features with predictable, efficient execution as required for critical embedded systems. I think that it will be more and more difficult to extend and evolve Ada in both directions (high-level, expressive, dynamic; vs. low-level, predictable, static) without in practice dividing the language into two: a "high-Ada" and a "low-Ada", with some compilers targeting the high and others the low. A bit of that can already be seen now, with some compilers supporting only some Ada standards and some limited profiles such as Ravenscar. This division may be the only way to support further Ada-style programming at both high and low levels. It may not be too bad a thing, as long as there is a decent amount of overlap (common middle ground) between high-Ada and low-Ada. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .