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=-0.9 required=5.0 tests=BAYES_00,FORGED_GMAIL_RCVD, FREEMAIL_FROM autolearn=no autolearn_force=no version=3.4.4 X-Received: by 2002:a5d:8509:: with SMTP id q9mr9275532ion.1.1546730950145; Sat, 05 Jan 2019 15:29:10 -0800 (PST) X-Received: by 2002:a9d:2c22:: with SMTP id f31mr1139472otb.4.1546730949951; Sat, 05 Jan 2019 15:29:09 -0800 (PST) Path: eternal-september.org!reader01.eternal-september.org!feeder.eternal-september.org!border1.nntp.ams1.giganews.com!nntp.giganews.com!feeder1.cambriumusenet.nl!feed.tweak.nl!209.85.166.216.MISMATCH!q69no450262itb.0!news-out.google.com!v141ni350ita.0!nntp.google.com!q69no450259itb.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Sat, 5 Jan 2019 15:29:09 -0800 (PST) In-Reply-To: <9e6b4219-d6ba-4c89-814d-5ea6e48ed8ea@googlegroups.com> Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=70.109.61.2; posting-account=QF6XPQoAAABce2NyPxxDAaKdAkN6RgAf NNTP-Posting-Host: 70.109.61.2 References: <2a6929c5-72fa-4d84-953a-44ea4597ab38@googlegroups.com> <9e6b4219-d6ba-4c89-814d-5ea6e48ed8ea@googlegroups.com> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: Subject: Re: class wide iterable (and indexable) From: Jere Injection-Date: Sat, 05 Jan 2019 23:29:10 +0000 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Xref: reader01.eternal-september.org comp.lang.ada:55206 Date: 2019-01-05T15:29:09-08:00 List-Id: On Friday, January 4, 2019 at 7:20:27 AM UTC-5, George Shapovalov wrote: > > > > Besides linking various type hierarchies together, interfaces are goo= d for containing common code that does not care about specific data storage= details. > >=20 > > No, interfaces cannot contain common code except for class-wide one.=20 > Yes, I have meant the class-wide methods here of course. Although I must = admit I wished more than once that non null/abstract methods that could be = inherited and overriden are allowed. Of course they could only reference o= ther methods (as the data is non-existent at this point), all eventually op= erating on the abstract/null primitives that are essentially "axioms" of th= e specific interface. But thus one could provide meaningful abstracted func= tionality that could be overriden in a sane way, removing the need for var= ious tricks, one of which you show in your comment.=20 You can using a Mixin Generic along with the interface. Consider the following example: ******************************************* with Ada.Text_IO; use Ada.Text_IO; procedure Hello is package Some_Interface is =20 type The_Interface is limited interface; function f1(Self : The_Interface) return Integer is abstract; function f2(Self : The_Interface) return Integer is abstract; function f3(Self : The_Interface) return Integer is abstract; =20 generic type Base is tagged limited private; package Mixin is type Derived is new Base and The_Interface with null record; overriding function f1(Self : Derived) return Integer; overriding function f2(Self : Derived) return Integer; overriding function f3(Self : Derived) return Integer; end Mixin; =20 end Some_Interface; =20 package body Some_Interface is package body Mixin is function f1(Self : Derived) return Integer is begin return 10; end f1; function f2(Self : Derived) return Integer is begin return 20; end f2; function f3(Self : Derived) return Integer is begin return Self.f1 + Self.f2; end f3; end Mixin; end Some_Interface; =20 -- For examples using existing inheritance trees we need -- a base type type Third_Party_Base is tagged null record; =20 package Examples is =20 use Some_Interface; =20 type Example_1 is limited new The_Interface with private; =20 type Example_2 is new Third_Party_Base and The_Interface with priva= te; =20 private =20 ----------------------------------------------- -- Packages ----------------------------------------------- =20 -- For situations where you have no regular base class, -- this is needed for the Mixin contract type Secret_Base is tagged limited null record; package Example_1_Pkg is new Mixin(Base =3D> Secret_Base); =20 -- For situations where you already have a base class, the -- instantiation is simpler. package Example_2_Pkg is new Mixin(Base =3D> Third_Party_Base); =20 -- ****NOTE: You can chain multiple mixins to get defaults for=20 -- various interfaces. For Example: -- package A_Pkg is new A_Mixin(Base =3D> Some_Base); -- package B_Pkg is new B_Mixin(Base =3D> A_Pkg.Deriv= ed); -- This will add both interfaces from A_Mixin and B_Mixi= n -- to the base type. =20 ----------------------------------------------- -- Full Type Declarations ----------------------------------------------- =20 type Example_1 is limited new Example_1_Pkg.Derived with null recor= d; =20 type Example_2 is new Example_2_Pkg.Derived with null record; =20 end Examples; begin Put_Line("Hello, world!"); end Hello; ******************************************* However, note that the defaults follow the basic Ada rules. They don't redispatch unless you specify that (For example in f3 you would do things like The_Interface'Class(Self).f1 and so on). So you have to decide what you want those defaults really do. Redispatch is fairly dangerous to do in Ada since it is not the default for inherited programs. I would=20 caution against it unless you have a real need and know what you are doing.