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: Tue, 8 Jan 2019 10:51:08 +0100 Organization: Aioe.org NNTP Server Message-ID: References: <2a6929c5-72fa-4d84-953a-44ea4597ab38@googlegroups.com> NNTP-Posting-Host: i065DRYuysvTI4qVnaNkyg.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 Content-Language: en-US X-Notice: Filtered by postfilter v. 0.8.3 X-Mozilla-News-Host: news://news.aioe.org Xref: reader01.eternal-september.org comp.lang.ada:55242 Date: 2019-01-08T10:51:08+01:00 List-Id: On 2019-01-07 22:07, Randy Brukardt wrote: > "Dmitry A. Kazakov" wrote in message > news:q0pvlp$1vp1$1@gioia.aioe.org... >> On 2019-01-05 10:21, Randy Brukardt wrote: >>> "Dmitry A. Kazakov" wrote in message >>> news:q0n6av$1tqs$1@gioia.aioe.org... >>> ... >>>> In real programs dispatch is rare, thus there is no overhead. >>> >>> This is probably true, but then interfaces are even more useless (they >>> provide nothing that could possibly be of value other than dispatch!). >> >> From the SW design POV they provide a description of an interface, which >> is a lot of value as is. > > That's primarily the job of package specifications, how the contents are > structured isn't very relevant from a description standpoint. Package specification is only a container for. How do you know that a type is numeric? The choice is between structural and named equivalence. With interfaces you can declare it numeric by merely stating that it belongs to the class. Without them you need to analyze all declarations related to the type in order to guess and there no guaranty that the guess is right. >>>> No, interfaces cannot contain common code except for class-wide one. Is >>>> that what Randy meant about overhead? >>> >>> Not really. My main point is that you'll never have more than one concrete >>> instance of a generic interface in any individual program (certainly not >>> of an interface like that of a container), >> >> I don't understand this. Usually I have dozens of instantiations of the >> same generics with different actual parameters. > > Right, but all of those are *different* interfaces because they have > *different* generic parameters. You can't mix those types in any useful way, > because you almost always have the generic parameter type(s) involved. Of course I can mix them. Generics are mixed by passing to other generics: generic with package X is new P (<>); package Mixer is ... The body is valid for all instances of P. And we still have not specialization of generics. So the set of instances cannot be constrained later. Though, I don't see how it is important to mix or not to mix instances to the question which method of building a class is better. Tagged classes are infinitely better than generic classes. > For instance, for the containers, an interface would have to contain the > element type. But that substantially limits reuse, because almost every > container instance would have a different element type. You can't even pass > just the interface into a generic because you wouldn't be able to call the > primitives without knowing the element type. To make such a reuse possible > you'd have to pass so many parameters that you are typing instantiations for > days. And then the compilation time also would be days. You'd have to be > slightly mad to even try it. :-) I don't see your point. You argue that generic-based design of containers is bad. Of course it is bad. >>> Note: I mean one concrete type, there might be many objects of that type. >>> But it doesn't make sense to use bounded and indefinite containers at the >>> same time for the same element type. >> >> Of course it does. The best example is Ada strings, a container of >> characters. Practically every program in effect uses both bounded and >> unbounded strings, the later, maybe, in the form of access String (I tend >> to avoid Unbounded_String). > > As with many things OOP, there seems to be exactly one example where it > works. And everything else it doesn't work (or at least help - it "works" in > the sense that you can write it that way and get it to work -- but you've > gained nothing, you've just changed the problems). At least there is one. Generics have none. >>> Dmitry is of course an all-interface all the time sort of guy. All I see >>> from that is a vast amount of typing to get nothing in particular in >>> return. >> >> You get type safety. Otherwise you can always go back K&R C! (:-)) > > Ada has plenty of type safety without using OOP. No, Ada is all OOP as we do type I is new Natural; -- Interface instead of type I is private; -- Nobody knows what function "+" (Left, Right : I) return I; function "-" (Left, Right : I) return I; function "*" (Left, Right : I) return I; function "/" (Left, Right : I) return I; function "0" return I; function "1" return I; function "2" return I; ... >>> [But I'm not much of a fan of OOP, either; the big advantage of OOP is >>> requiring few recompiles when adding features. That was a big deal in >>> 1990, >>> but it hardly matters today. (I can recompile the entirety of Janus/Ada - >>> 250,000 lines - in 15 minutes or so. Why try to save compiles?) And for >>> that, you get to type dozens and dozens of declarations to do anything. >> >> That is because compilers are no longer large software, not even >> medium-size (:-)). My current project takes a half of week to recompile >> from scratch [*]. > > Because you greatly overuse generics in the hopes of making interfaces > useful. [You admitted as much at the bottom of this message.] You understand > the cost of using interfaces very well, yet don't seem to make the obvious > connection. ;-) There is no other way to reuse across a set of types. Either generics (AKA static polymorphism) or inheritance (AKA dynamic polymorphism). >> And recompilation is not the biggest problem. Deployment of the modules >> is. > > Keeping protocols consistent is definitely a hard problem. (One I'm glad to > skip.) I don't see any reason that OOP would help there, though. My attempt > at that in the Claw Builder was mostly unsuccessful. With interfaces you can detect client side problems at compile time. Without them you don't know until you actually use a given operation. This is the case with generics especially because Ada generics have weak contracts. > And you talk about this a lot, so I don't know what it is that you think you > gain with interfaces that you wouldn't have with a normal record type and > primitive operations. Give me tagged types to freely inherit from and I promise to never use interfaces [*] again! (:-)) >> ---------------------- >> * GNAT is awfully slow when compiling specifically generic instantiations, >> and I have lots of them. The more I have, the more I hate them. > > This is the point where I'd usually suggest trying a different compiler. :-) And I usually point out that without Linux/VxWorks support and targets like ARM there is no chance. > A compiler using shared generics could take a lot less time to compile > instances because there is little code involved. Without any doubt. Worse that that, yes, instances are slow to compile, but I have an impression that merely with-ing compiled instances drastically increases the compile time of a package and the memory used by the compiler. At the end of the dependency chain it becomes minutes to compile a three-liner body. There is something utterly wrong with GNAT there. > OTOH, I don't want you to > try Janus/Ada (even on the code that don't use actual interfaces), 'cause > the way you use generics would inevitably break stuff and I'd hate to have > to debug code like that. :-) :-) I would gladly use Janus/Ada or ObjectAda if I could. I was a happy user of the latter long ago. Unfortunately cross-platformity is a requirement in these days. -------------------- * Here, interface = crippled abstract tagged type. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de