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: border1.nntp.dca3.giganews.com!backlog3.nntp.dca3.giganews.com!border2.nntp.dca.giganews.com!nntp.giganews.com!newspeer1.nac.net!newsfeed.xs4all.nl!newsfeed2a.news.xs4all.nl!xs4all!news.stack.nl!reality.xs3.de!news.jacob-sparre.dk!loke.jacob-sparre.dk!pnx.dk!.POSTED!not-for-mail From: "Randy Brukardt" Newsgroups: comp.lang.ada Subject: Re: Your wish list for Ada 202X Date: Fri, 18 Apr 2014 16:28:58 -0500 Organization: Jacob Sparre Andersen Research & Innovation 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> NNTP-Posting-Host: static-69-95-181-76.mad.choiceone.net X-Trace: loke.gir.dk 1397856541 17313 69.95.181.76 (18 Apr 2014 21:29:01 GMT) X-Complaints-To: news@jacob-sparre.dk NNTP-Posting-Date: Fri, 18 Apr 2014 21:29:01 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5931 X-RFC2646: Format=Flowed; Original X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157 X-Original-Bytes: 7552 Xref: number.nntp.dca.giganews.com comp.lang.ada:185827 Date: 2014-04-18T16:28:58-05:00 List-Id: "Niklas Holsti" wrote in message news:brdegqFi62jU1@mid.individual.net... > On 14-04-17 01:27 , Randy Brukardt wrote: >> "Niklas Holsti" wrote in message >> news:br8bu5Fg3keU1@mid.individual.net... >>> On 14-04-15 03:08 , Randy Brukardt wrote: ... >> There's also the point that a >> dispatching call always has to be assumed to be to some body not even >> written yet, so it's nearly impossible to say anything definitive about >> it's >> contract. > > But the operation has been *specified*, even if no bodies exist, > therefore the contract *from the caller's point of view* should have > been defined. Otherwise there is not much point in using a class at all, > or indeed in separating operation declarations and bodies. Right, but here I'm a practicalist, rather than theortician. Humans write programs, and they tend to ignore anything not convinient. That certainly goes for whatever part of the contract is not formally specified and checked. So there is a lot more risk from re-dispatching than static binding, simply because there is more likelihood of error (unintentional or malicious). >> ... >>>> This last issue doesn't arise for a class-wide operation, where every >>>> call is going to look at an object of TT as type TT. >>> >>> Except if TT inherits some operation from T, because then that operation >>> looks at the object as type T. (I know that from the language-semantics >>> point of view the inherited operation acts on TT, but the programmer >>> wrote its code with T in mind.) >>> >>> If redispatching is suspect because it breaks the assocation of an >>> operation with a unique type, then inheritance of operations must also >>> be suspect, for the same reason. >> >> I understand your point, but I think the language-semantics view is >> actually >> the correct one. One only allows inheritance of operations when the >> implementation for T and for TT is thought to be identical. One hopes >> that >> the author of TT considered that carefully! > > Well, I use redispatching only when I think that the operation being > called is well specified and is or will be carefully implemented for > each type in the class, as appropriate for that type. Same difference :-) If you truly believe that you can "well specify" and "carefully implement" everything in your system, well, you're a better man than me. :-) I don't believe that about my code even when I write the entire thing at one time - much less when other people are involved or years pass between work. One of the things that attracted me to Ada in the first place is that it forces me to specify enough that it prevents many of my worst impulses. (Instantiating Unchecked_Conversion is painful enough to prevent most reuse of objects, for one example.) I doubt I'd ever get a lengthy C program to work! >> It's true that maintenance of the T operation might in fact break the TT >> operation (meaning that they should have different implementations), so >> there is some additional danger in inheritance. > > Yes. In general, the more a program is "factored" into parts that are > combined and invoked in many contexts, the harder it becomes to maintain > proper behaviour in all contexts. Subprograms, inheritance, dispatching, > redispatching all tend in this direction. Right. >> There is also danger in >> inheritance that the author of TT didn't know about. (I think it would be >> much better if all inheritance was explicit; but to be practical that >> would >> require a rather different syntax than Ada uses, and thus such a thing >> would >> not make sense in an Ada perspective. > > To make inheritance explicit, it seems to me that each inherited > operation must be declared for the derived type, with its full profile, > perhaps as > > inherited procedure Foo (X: in T; ....); > > This would require just one new reserved word, "inherited", and does not > feel like a "rather different syntax". Did you have something else in > mind? The problem with this sort of syntax is that it's really wordy and tends to obscure the important issues (which is not the exact profile, as least unless you have a resolution problem). Remember all of the people that used renames to avoid using use clauses for Ada 83? (Maybe not, that was a long time ago.) They often had bugs like: function "+" (Left, Right : P.Big_Int) return P.Big_Int renames P."-"; where the profile is obscuring the critical differences. I'd prefer a much simpler declaration of inheritance, something like: type Child is new Parent with ... with inherits => Foo, Bar, Blech; where names not listed are hidden from all visibility unless overridden. (The Ada dispatching model insists that the routines exist, so for Ada all one could do would be to hide any uninherited operations from direct calls. One could imagine have uninherited operations raise Program_Error in dispatching as an alternative, but that's not ideal either because it makes a tripping hazard as Bob calls it. Thirdly, one could require all operations to be either inherited or overridden, but that just makes a new kind of pain for deriving types, especially for those of us who prefer incremental implementation of things). Whether that's enough or if some alternative with optional profiles is necessary, I don't know. Most operations aren't overloaded, after all, so the profile is just noise. Randy.