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!feeder.eternal-september.org!aioe.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: class wide iterable (and indexable) Date: Fri, 11 Jan 2019 10:09:54 +0100 Organization: Aioe.org NNTP Server Message-ID: References: <2a6929c5-72fa-4d84-953a-44ea4597ab38@googlegroups.com> NNTP-Posting-Host: MyFhHs417jM9AgzRpXn7yg.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.4.0 X-Notice: Filtered by postfilter v. 0.8.3 Content-Language: en-US Xref: reader01.eternal-september.org comp.lang.ada:55263 Date: 2019-01-11T10:09:54+01:00 List-Id: On 2019-01-10 23:14, Randy Brukardt wrote: > "Dmitry A. Kazakov" wrote in message > news:q1715k$1fou$1@gioia.aioe.org... >> On 2019-01-10 00:38, Randy Brukardt wrote: > ... >>> That makes any interfaces >>> (again, Ada interface feature) involved useless, as they're necessarily >>> different than any other such interfaces, which means there isn't >>> anything >>> that you can do with them. So why have them at all? >> >> You mean declaring an interface inside the generic? > > Yes, because that's the only possibility if the interface has to be > parameterized by a type in some way (as a container interface has to be). > And most objects end up being parameterized by a type, else they tend to be > single purpose (and those types tend not to be like any other). No, that is the way parametric polymorphism = generics works. Ada interfaces are dynamic polymorphism and must be used accordingly. E.g. by using an explicit class of elements to be constrained later in the instances. (For a hammer everything is a nail) >>> Making the elements much more expensive (because of the need to manage an >>> expensive tag) than they otherwise would be. There's a lot of pushback on >>> even making language-defined units tagged, because of overhead concerns. >>> (Don't buy that myself, but that's the mindset.) >> >> Yes, but this is another roadblock. Elements of containers should be >> externally tagged by-value types. That would eliminate the overhead. > > That pushes the cost to other places (i.e. parameter passing instead of > object declaration). I was including that model in my thinks (not > necessarily in the thinking of others, of course). Tucker calls this the > "bump under the carpet" problem. You can move the bump around, but you can't > get rid of it. It is the same mechanism that is used for passing array bounds. And if statically known (and all parents are abstract) the constraint can be eliminated altogether, again like with arrays. You might be required to adjust inherited operations, but again, this is no different from what you do with shared generic bodies. > Ada probably can't use the separate tag model because of its insistence on > supporting redispatching, even in inherited routines. I think you've > convinced me that model was a mistake, but like many things in existing Ada, > we're stuck with it short of a drastic (not completely compatible) redesign. There is no view conversions for such types, they are by-value. Thus no way to even spell re-dispatch. Conversion to Parent'Class will create a new object. >>> Anyway, #1 has to be part of the contract of the generic. Doesn't make sense >>> otherwise. And packaging all of the contracts into a single entity has been >>> tried in many ways (that's the original reason for formal packages, the >>> so-called signature package) -- and it's always too inflexible. Best to just >>> have the individual requirements clearly stated in the profile of the >>> generic. (I'd have said "interface", meaning the concept, not the feature, >>> but that gets too confusing.) >> >> Sure. It is the same problem in both cases. The solution that would work >> for generics is exactly the interfaces (universal) I am talking about. >> Presently, it is only tagged contracts that are allowed (tagged type or >> Ada interface). And they work perfectly. If we introduced externally >> tagged contracts they would work out of the box just same. Ah, but we >> would not need generics then... > > I don't quite see how that would work. That is another question. I only say that if you want stronger generic contracts then instead of generic type T is range <>; you must have generic type T is new Signed_Integer with private; Exactly one type of formal generic type. All RM 12.5 to be a two-liner. > The place where interfaces (some more general feature than the one Ada has!) > are useful is the case where you have to decouple the interface from > representation. I find this a rare need that shows up mainly in the > language-defined libraries (obviously YMMV). But it shows up there in a > mammoth way. In my view interface and implementation must be always separated. There are cases when the representation could be directly deduced from the interface. Only these require no explicit declaration of representation. > I start to wonder why (other than > compatibility) we have built-in array types at all; just make a fixed > container similar to vectors for what is now arrays. Right. Arrays, records, access types must be interfaces with built-in implementations. > In any case, I see the theroetical advantages of having some sort of > interface mechanism, but I just don't see the uses in practice that make > them a feature worth all of the implementation and definitional > complication. It would make Ada a very small language. For developers it would ease using Ada immensely. > For instance, we tried for a long time to work out rules that would allow > hidden interfaces, but we just could not come up with anything that wasn't > full of surprising cases or that totally destroyed privacy. That last thing > anyone wants is their type extensions to do surprising things. We even > restarted that a few years ago, but the solutions just get ridiculously > complex. Interfaces should be allowed to be additive with the corresponding rules to resolve conflicting implementations. There is an obvious contradiction between invisibility and idempotence, e.g. if one entity is visible and other is not. Let them add up and require conflict resolution in the contexts where both become visible. > The sort of model you are suggesting would lead directly to the same sort of > issues. And the problem with "obscure" corner-cases that are incompatible is > that they tend to keep people from upgrading even if the language design is > better off with them. Because almost everyone has code that depends on some > of those obscure corner cases. Not if the model is universal enough to express all existing quirks. I agree that nothing drastic could be resolved at the existing level of abstraction. That is why Ada must move one step up. > So, to do that sort of overhaul, you'd have to find a willingness to accept > various incompatibities, and some group motivated enough to work out all of > the details. Probably need the $$$ again. And it probably would be better > off to start from scratch semantically in that case, because then you don't > have to reproduce most of the warts. No, I don't believe that either. See how people keep on creating C. There is a dozen of C-like languages redesigned from scratch, but the warts are all there. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de