From: "Randy Brukardt" <randy@rrsoftware.com>
Subject: Re: T'Interface attribute
Date: Fri, 4 Aug 2017 18:51:45 -0500
Date: 2017-08-04T18:51:45-05:00 [thread overview]
Message-ID: <om31ai$ecu$1@franka.jacob-sparre.dk> (raw)
In-Reply-To: oluj7t$8uo$1@gioia.aioe.org
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
news:oluj7t$8uo$1@gioia.aioe.org...
> On 2017-08-03 06:46, Randy Brukardt wrote:
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> 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.
next prev parent reply other threads:[~2017-08-04 23:51 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-02 13:43 T'Interface attribute Dmitry A. Kazakov
2017-08-02 14:23 ` Eryndlia Mavourneen
2017-08-03 12:52 ` Dmitry A. Kazakov
2017-08-03 4:46 ` Randy Brukardt
2017-08-03 7:26 ` Dmitry A. Kazakov
2017-08-04 23:51 ` Randy Brukardt [this message]
2017-08-05 7:49 ` Dmitry A. Kazakov
2017-08-07 22:59 ` Randy Brukardt
2017-08-08 6:13 ` Dmitry A. Kazakov
2017-08-09 0:38 ` Randy Brukardt
2017-08-09 7:06 ` Dmitry A. Kazakov
2017-08-09 23:03 ` Randy Brukardt
2017-08-10 7:13 ` Dmitry A. Kazakov
2017-08-11 0:33 ` Randy Brukardt
2017-08-11 6:55 ` Dmitry A. Kazakov
2017-08-11 20:49 ` Randy Brukardt
2017-08-03 17:27 ` Eryndlia Mavourneen
2017-08-05 0:09 ` Randy Brukardt
2017-08-05 19:02 ` Eryndlia Mavourneen
2017-08-07 22:49 ` Randy Brukardt
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox