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: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!gegeweb.org!news.ecp.fr!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: Wed, 16 Apr 2014 17:27:18 -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 1397687240 31316 69.95.181.76 (16 Apr 2014 22:27:20 GMT) X-Complaints-To: news@jacob-sparre.dk NNTP-Posting-Date: Wed, 16 Apr 2014 22:27:20 +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 Xref: news.eternal-september.org comp.lang.ada:19340 Date: 2014-04-16T17:27:18-05:00 List-Id: "Niklas Holsti" wrote in message news:br8bu5Fg3keU1@mid.individual.net... > On 14-04-15 03:08 , Randy Brukardt wrote: ... >> Dispatching operations necessarily have weaker contracts than statically >> bound calls, and that is especially important for "contracts" that can't >> be >> described in Ada and thus can't be checked (either statically or >> dynamically). > > Hm, I'm not convinced of that. To me, the informal contract for a > dispatching operation Foo is "implements the Foo operation as specified > for the class and as appropriate for the actual type". Of course these > specifications are given in comments. A lot of our discussion has become subjective, and I don't know if there is a lot to be learned comparing somewhat different world-views. So I'm only going to respond to a couple of points here... Anyway, there is two problems with "specifications given in comments": (A) they can't be checked in any automatic or formal way. When humans are involved, mistakes *will* occur, and if they're not checked, the results could be disasterous. After all, we just got a lesson in that from OpenSSH. Had OpenSSH had a formal contract, the problem could not have ever leaked any information. (If the contract was enforced only at runtime, like Pre in Ada, OpenSSH might have had at worst a denial-of-service problem, but that would have been quickly fixed and most of us would have never heard anything about it.) (B) English (or other natural language) is ambiguous, and such comments often only make sense to the author (and recently at that). I often spend as much time decoding old comments (even ones I wrote years ago) than actually fixing anything in Janus/Ada these days. There's a decent percentage that only make sense if one adds a lot of context to them (and of course a few that defy ever making sense). > I don't see the "necessarily ... weaker" for the more formal contracts > either. Yes, for a dispatching call there are more possible callee > operations (implementations) to check against the contract, but the > general contract (as experienced by the caller) can be the same for all. LSP says that preconditions have to combine weaker in order for dispatching calls to make sense. Whether LSP is really the last word on OOP is an open question, but if you mean to follow it, at least part of the contract *has* to be weaker in a dispatching call. 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. (Pre'Class and the like are supposed to solve this latter problem, but they have a bug involving (guess what) redispatching so they might not. At least until the ARG considers the bug, which I really need to write up one of these days.) >> After all, most extensions are created by someone other than >> the originator of the original class, > > Not (sadly) the case for my applications. But sometimes years go by > between the definition of the class and the addition of a derived type, > so memory can play tricks, and I have had a few hiccups in that area. > But not many, perhaps thanks to my obsessive commenting. Commenting is good, but formal contracts are better, simply because they require you to write the contract in terms that mean the same thing when you come back to them in 5 years. And then the additional value provided by checking is gravy to people that truly do comment everything. ... ... >> 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! 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. 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. For Claw, we had to write a tool to figure out what operations exist for each concrete type, as there are so many primitive operations and so many inheritance trees that it was completely impossible to keep them straight by hand. I've never been a fan of the way inheritance is handled in Ada.) > I suppose one could forbid both inheritance and redispatching. That > would be a major departure from traditional object/class-oriented > programming. Not forbid so much as "require declaration of". Ada already does that for redispatching; my opinion is that it should be used rarely, but as with all such tools (e.g. goto), rarely is certainly not never. Twisting a design around to avoid redispatching is not likely to improve anything. Similarly, inheritance can cause issues, but a lot of the time it also saves implementing the same thing five times in a row. (The fact that I couldn't make inheritance work for implementing parts of the Claw Builder is a significant part of why it became close to unmaintainable.) My mantra tends to be that programming languages are better when everything is explicit - because when programmers and compilers are assuming stuff, it's not unlikely that the assumptions end up different. And that's when trouble happens. Randy.