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!feeder.eternal-september.org!nntp-feed.chiark.greenend.org.uk!ewrotcd!newsfeed.xs3.de!io.xs3.de!news.jacob-sparre.dk!franka.jacob-sparre.dk!pnx.dk!.POSTED.rrsoftware.com!not-for-mail From: "Randy Brukardt" Newsgroups: comp.lang.ada Subject: Re: T'Interface attribute Date: Fri, 4 Aug 2017 18:51:45 -0500 Organization: JSA Research & Innovation Message-ID: References: Injection-Date: Fri, 4 Aug 2017 23:51:46 -0000 (UTC) Injection-Info: franka.jacob-sparre.dk; posting-host="rrsoftware.com:24.196.82.226"; logging-data="14750"; mail-complaints-to="news@jacob-sparre.dk" X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5931 X-RFC2646: Format=Flowed; Response X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.7246 Xref: news.eternal-september.org comp.lang.ada:47594 Date: 2017-08-04T18:51:45-05:00 List-Id: "Dmitry A. Kazakov" wrote in message news:oluj7t$8uo$1@gioia.aioe.org... > On 2017-08-03 06:46, Randy Brukardt wrote: >> "Dmitry A. Kazakov" wrote in message >> news:olskua$1bfd$1@gioia.aioe.org... >>> In order to reduce name space contamination I would propose attribute >>> T'Interface which for any tagged type T would denote an interface type >>> with all *new* primitive operations, e.g. >> >> Past experience say that such attributes (that is, those that designate >> some >> sort of type or subtype) don't work out very well in Ada. For instance, >> we >> considered T'Access in Ada 2005, but gave that up because of various >> problems (and replaced with with anonymous access types, which are >> worse). >> The worst problem was that there was no limit to the attribute, you could >> write T'Access'Access'Access - and you can't prevent this since T could >> be a >> generic formal type that itself is some T'Access. > > In this case generic would not be a problem because T must be tagged to > have T'Interface. > > As a side note, differently to 'Access, 'Length and actually 'Class, > 'Interface is idempotent: > > T'Interface ::= T'Interface'Interface Ada defines 'Class this way, too, I think in part to mitigate these problems. The problem with formals is from the actual being T'Interface: generic type T is abstract tagged private; package Gen is procedure P (Item : in T'Interface); end Gen; package Inst is new Gen (Some_Tagged_Type'Interface); The parameter of P is essentially Some_Tagged_Type'Interface'Interface. >> Almost all Ada compilers materialize all Ada types in their symbol table, >> so >> the effect of having a T'Interface would be that it would be >> automatically >> declared for all tagged type declarations. Most Ada compilers also >> materialize all of the primitive operations in their symbol table, so >> there >> would be a large increase in memory usage and some time increase (all >> lookups would have twice as many primitives to look through). > > This is an intended effect. Yes, there would likely be two tags for each > declared type. > > Which by the way will fix Ada.Streams and System.Storage_Pools design for > free. Since we will finally have: > > Root_Stream_Type'Interface > > and > > Root_Storage_Pool'Interface > > E.g. > > type Serialized_Widget is > new Gtk_Widget_Record and Root_Stream_Type'Interface with private; The problem with "fixing" Root_Stream_Type etc. is the "no hidden interfaces" rule. These types are often used in private derivations, and that is illegal for interfaces. (Attempts to weaken the "no hidden interfaces" rule have led to various definitional nightmares - it does not look likely. AI12-0023-1 discusses the latest attempts - it's still open but hasn't been discussed since Stockholm.) That suggests a problem with this idea: effectivelly all types would have an associated interface. But interfaces can never be hidden (certainly not without restrictions as discussed in AI12-0023-1), so that would seem to imply that no hidden type derivations could occur. That would be a massive compatibility problem. >> P.S. And as always, explain the problem to be solved as well as the >> possible >> solution. That is always necessary to understand the value of a proposal. > > I have a design rule to have an explicit interface declared for each > tagged type. It saves much of redesign later. I've generally materialized that as "the root of an abstraction should always be declared abstract". >> P.P.S. I personally have never seen a real-world example where an >> interface >> actually helps. There's lots and lots of book examples and show examples >> and >> so on, but in practice you end up with only a single implementation so >> there >> really is nothing gained by involving a lot of dispatching calls. Ergo, >> I'm >> against anything (new) involving interfaces. YMMV. > > I have no idea how you manage keep Claw out of interfaces, really. > Multiple inheritance is a huge help and relief. I am using interfaces > extensively unless backward Ada 95 compatibility hinders me. E.g. in AICWL > all widget layers implement interfaces like Scalable_Layer, Gauge_Needle, > Waveform_Amplifier etc. It would not work otherwise. In Claw, the only places that we got much benefit from OOP (beyond dispatching callbacks, the reason we used OOP in the first place) was in sharing implementations across related types. But that doesn't work for Ada interfaces, because you can't have any components in the type -- meaning that writing real implementations is impossible. One can use abstract types in this way (and we did so extensively). We didn't find much use for dispatching (outside of the callbacks as previously mentioned; those only need to work on root types since they come directly from the message loop engine). If you don't need (or can use) dispatching, and since you can't use implementation inheritance, the use of interfaces buys nothing. (Of course, we didn't have interfaces when Claw was designed, so it wasn't even an option. Perhaps we'd have done something differently had they been available -- but I doubt it.) That pattern has persisted in pretty much all of my recent programs; I don't usually have very deep hierarchies and dispatching is limited to the root types (which I declare abstract for maximum sharing). I realize other people end up with other patterns, but I'm not going to champion something I don't find useful. (I doubt I could do a good job of championing it anyway). Randy.