* Controlled types as interfaces
@ 2014-08-20 1:05 Victor Porton
2014-08-20 1:09 ` Victor Porton
2014-08-20 1:41 ` Victor Porton
0 siblings, 2 replies; 13+ messages in thread
From: Victor Porton @ 2014-08-20 1:05 UTC (permalink / raw)
I think in Ada 202X we can invent Limited_Controlled_Interface and
Controlled_Interface types derived from which could become controlled.
The Limited_Controlled and Controlled types would also inherit from these
interfaces.
I think, this is backward compatible.
Good idea?
--
Victor Porton - http://portonvictor.org
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Controlled types as interfaces
2014-08-20 1:05 Controlled types as interfaces Victor Porton
@ 2014-08-20 1:09 ` Victor Porton
2014-08-20 7:29 ` Dmitry A. Kazakov
2014-08-20 1:41 ` Victor Porton
1 sibling, 1 reply; 13+ messages in thread
From: Victor Porton @ 2014-08-20 1:09 UTC (permalink / raw)
Victor Porton wrote:
> I think in Ada 202X we can invent Limited_Controlled_Interface and
> Controlled_Interface types derived from which could become controlled.
>
> The Limited_Controlled and Controlled types would also inherit from these
> interfaces.
>
> I think, this is backward compatible.
A similar thing can be made with Root_Stream_Type making it derived from
Root_Stream_Interface interface.
--
Victor Porton - http://portonvictor.org
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Controlled types as interfaces
2014-08-20 1:05 Controlled types as interfaces Victor Porton
2014-08-20 1:09 ` Victor Porton
@ 2014-08-20 1:41 ` Victor Porton
1 sibling, 0 replies; 13+ messages in thread
From: Victor Porton @ 2014-08-20 1:41 UTC (permalink / raw)
Victor Porton wrote:
> I think in Ada 202X we can invent Limited_Controlled_Interface and
> Controlled_Interface types derived from which could become controlled.
>
> The Limited_Controlled and Controlled types would also inherit from these
> interfaces.
>
> I think, this is backward compatible.
>
> Good idea?
And then we would deprecate old types Limited_Controlled and Controlled
because the interfaces do the job better.
--
Victor Porton - http://portonvictor.org
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Controlled types as interfaces
2014-08-20 1:09 ` Victor Porton
@ 2014-08-20 7:29 ` Dmitry A. Kazakov
2014-08-20 12:49 ` Victor Porton
2014-08-20 12:50 ` Victor Porton
0 siblings, 2 replies; 13+ messages in thread
From: Dmitry A. Kazakov @ 2014-08-20 7:29 UTC (permalink / raw)
On Wed, 20 Aug 2014 04:09:15 +0300, Victor Porton wrote:
> Victor Porton wrote:
>> I think in Ada 202X we can invent Limited_Controlled_Interface and
>> Controlled_Interface types derived from which could become controlled.
Yes, but that would be very complicated, because you could add an interface
very late, making a descendant of a non-controlled type controlled.
A better solution would be fixing initialization (AKA constructors) and
leaving controlled kludge as is.
>> The Limited_Controlled and Controlled types would also inherit from these
>> interfaces.
>>
>> I think, this is backward compatible.
>
> A similar thing can be made with Root_Stream_Type making it derived from
> Root_Stream_Interface interface.
Yes, of course. It was proposed multiple times, as I remember. But rejected
as "not backward compatible." Though the compatibility issue was quite
minor if any.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Controlled types as interfaces
2014-08-20 7:29 ` Dmitry A. Kazakov
@ 2014-08-20 12:49 ` Victor Porton
2014-08-20 13:47 ` Dmitry A. Kazakov
2014-08-20 12:50 ` Victor Porton
1 sibling, 1 reply; 13+ messages in thread
From: Victor Porton @ 2014-08-20 12:49 UTC (permalink / raw)
Dmitry A. Kazakov wrote:
> On Wed, 20 Aug 2014 04:09:15 +0300, Victor Porton wrote:
>
>> Victor Porton wrote:
>>> I think in Ada 202X we can invent Limited_Controlled_Interface and
>>> Controlled_Interface types derived from which could become controlled.
>
> Yes, but that would be very complicated, because you could add an
> interface very late, making a descendant of a non-controlled type
> controlled.
>
> A better solution would be fixing initialization (AKA constructors) and
> leaving controlled kludge as is.
I don't see any reason not to make descendant of a non-controlled type
controlled.
Let T is a non-controlled tagged type.
It descendant Q is like a record
record
Old: T;
Ext: Q1;
end record;
(where Q1 is the difference of Q and T).
Q1 is controlled.
As there is no problem that this record becomes controlled, there are no
reason not to make Q controlled despite of T was non-controlled.
--
Victor Porton - http://portonvictor.org
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Controlled types as interfaces
2014-08-20 7:29 ` Dmitry A. Kazakov
2014-08-20 12:49 ` Victor Porton
@ 2014-08-20 12:50 ` Victor Porton
2014-08-20 13:38 ` Dmitry A. Kazakov
2014-08-20 13:56 ` Brad Moore
1 sibling, 2 replies; 13+ messages in thread
From: Victor Porton @ 2014-08-20 12:50 UTC (permalink / raw)
Dmitry A. Kazakov wrote:
>> A similar thing can be made with Root_Stream_Type making it derived from
>> Root_Stream_Interface interface.
>
> Yes, of course. It was proposed multiple times, as I remember. But
> rejected as "not backward compatible." Though the compatibility issue was
> quite minor if any.
We can make Root_Stream_Type a descendant of Root_Stream_Interface.
So old code can derive from Root_Stream_Type and this is backward
compatible.
--
Victor Porton - http://portonvictor.org
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Controlled types as interfaces
2014-08-20 12:50 ` Victor Porton
@ 2014-08-20 13:38 ` Dmitry A. Kazakov
2014-08-20 13:56 ` Brad Moore
1 sibling, 0 replies; 13+ messages in thread
From: Dmitry A. Kazakov @ 2014-08-20 13:38 UTC (permalink / raw)
On Wed, 20 Aug 2014 15:50:58 +0300, Victor Porton wrote:
> Dmitry A. Kazakov wrote:
>
>>> A similar thing can be made with Root_Stream_Type making it derived from
>>> Root_Stream_Interface interface.
>>
>> Yes, of course. It was proposed multiple times, as I remember. But
>> rejected as "not backward compatible." Though the compatibility issue was
>> quite minor if any.
>
> We can make Root_Stream_Type a descendant of Root_Stream_Interface.
Yes that was exactly the proposal (and for the pool's root type as well).
> So old code can derive from Root_Stream_Type and this is backward
> compatible.
No. It was a different case. I don't remember the details. But the example
was quite marginal and wrong code anyway, as I remember.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Controlled types as interfaces
2014-08-20 12:49 ` Victor Porton
@ 2014-08-20 13:47 ` Dmitry A. Kazakov
2014-08-21 23:16 ` Randy Brukardt
0 siblings, 1 reply; 13+ messages in thread
From: Dmitry A. Kazakov @ 2014-08-20 13:47 UTC (permalink / raw)
On Wed, 20 Aug 2014 15:49:36 +0300, Victor Porton wrote:
> Dmitry A. Kazakov wrote:
>
>> On Wed, 20 Aug 2014 04:09:15 +0300, Victor Porton wrote:
>>
>>> Victor Porton wrote:
>>>> I think in Ada 202X we can invent Limited_Controlled_Interface and
>>>> Controlled_Interface types derived from which could become controlled.
>>
>> Yes, but that would be very complicated, because you could add an
>> interface very late, making a descendant of a non-controlled type
>> controlled.
>>
>> A better solution would be fixing initialization (AKA constructors) and
>> leaving controlled kludge as is.
>
> I don't see any reason not to make descendant of a non-controlled type
> controlled.
I don't see why any type cannot have initialization hooks either.
> Let T is a non-controlled tagged type.
>
> It descendant Q is like a record
>
> record
> Old: T;
> Ext: Q1;
> end record;
>
> (where Q1 is the difference of Q and T).
>
> Q1 is controlled.
>
> As there is no problem that this record becomes controlled, there are no
> reason not to make Q controlled despite of T was non-controlled.
It depends on concrete implementations, e.g. some might require the type
tag being at the record's first address.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Controlled types as interfaces
2014-08-20 12:50 ` Victor Porton
2014-08-20 13:38 ` Dmitry A. Kazakov
@ 2014-08-20 13:56 ` Brad Moore
2014-08-21 22:48 ` Randy Brukardt
1 sibling, 1 reply; 13+ messages in thread
From: Brad Moore @ 2014-08-20 13:56 UTC (permalink / raw)
On 14-08-20 06:50 AM, Victor Porton wrote:
> Dmitry A. Kazakov wrote:
>
>>> A similar thing can be made with Root_Stream_Type making it derived from
>>> Root_Stream_Interface interface.
>>
>> Yes, of course. It was proposed multiple times, as I remember. But
>> rejected as "not backward compatible." Though the compatibility issue was
>> quite minor if any.
>
> We can make Root_Stream_Type a descendant of Root_Stream_Interface.
>
> So old code can derive from Root_Stream_Type and this is backward
> compatible.
>
There is an amendment AI for this already, for Ada 202x.
See AI12-0023-1
(
http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0023-1.txt?rev=1.3&raw=Y
)
This AI has not been rejected (yet), as all amendment AI's that are
proposals for Ada 202X are only proposals at this point. At some point
in the future when it comes time to start selecting which proposals are
worth having, this AI may or may not make the cut.
The incompatibilities are described in the discussion section of the AI,
but these had to do with problems of changing Root_Stream_Type into an
interface.
However, I believe you are correct that if we modified Root_Stream_Type
to remain an abstract type that inherits from a Root_Stream_Interface,
then these incompatibilities would not exist.
Backward incompatibilities are to be avoided if at all possible, so I
think if we were to go forward with this AI, your suggestion to make
Root_Stream_Type inherit from a Root_Stream_Interface, might be the way
to go.
Brad
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Controlled types as interfaces
2014-08-20 13:56 ` Brad Moore
@ 2014-08-21 22:48 ` Randy Brukardt
0 siblings, 0 replies; 13+ messages in thread
From: Randy Brukardt @ 2014-08-21 22:48 UTC (permalink / raw)
"Brad Moore" <brad.moore@shaw.ca> wrote in message
news:1O1Jv.11735$8G3.5145@fx12.iad...
> On 14-08-20 06:50 AM, Victor Porton wrote:
...
> The incompatibilities are described in the discussion section of the AI,
> but these had to do with problems of changing Root_Stream_Type into an
> interface.
>
> However, I believe you are correct that if we modified Root_Stream_Type to
> remain an abstract type that inherits from a Root_Stream_Interface, then
> these incompatibilities would not exist.
No, sorry, they're the same. The problem is that Ada doesn't allow hidden
inheritance (in any way) of an interface.
If Root_Stream_Type is an interface, or inherits from an interface, then it
cannot be used in the full type definition of a private type. That's the
backwards incompatibility.
> Backward incompatibilities are to be avoided if at all possible, so I
> think if we were to go forward with this AI, your suggestion to make
> Root_Stream_Type inherit from a Root_Stream_Interface, might be the way to
> go.
We've already discussed that as-nausem. My personal opinion (in the case of
Root_Stream_Type) is that there isn't any good reason to use this in a
hidden way, so we could just make it an interface and swallow the
incompatibility. (When I suggested that at a meeting, though, it got no
traction.)
But that's not true for Controlled. The vast majority of the types I define
are tagged private where the full type is derived from Controlled (or
Limited_Controlled).
The most recent versions of AI12-0023-1 were trying to find ways to lift the
ban against hidden interfaces for a restricted set of interfaces. It's the
only way to do this without incompatibilities for existing uses. My
recollection is that it wasn't going well (but we haven't worked on that
since the Stockholm meeting more than a year ago).
Randy.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Controlled types as interfaces
2014-08-20 13:47 ` Dmitry A. Kazakov
@ 2014-08-21 23:16 ` Randy Brukardt
2014-08-29 15:01 ` Robert A Duff
0 siblings, 1 reply; 13+ messages in thread
From: Randy Brukardt @ 2014-08-21 23:16 UTC (permalink / raw)
"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
news:imjh3cg11wdr$.1hslpo3a68yxi.dlg@40tude.net...
> On Wed, 20 Aug 2014 15:49:36 +0300, Victor Porton wrote:
...
>> As there is no problem that this record becomes controlled, there are no
>> reason not to make Q controlled despite of T was non-controlled.
>
> It depends on concrete implementations, e.g. some might require the type
> tag being at the record's first address.
That's not exactly the problem, as Ada allows types with conflicting
representation clauses to be rejected. (This particular problem can already
happen for interfaces, so there are rules to handle it.)
The real problem is that some (many?) implementations include
implementation-defined components in types Controlled and
Limited_Controlled. (For instance, Janus/Ada includes chain components.)
Interfaces of course don't have any components; thus making
Controlled/Limited_Controlled into interfaces would require the back-door
implementation of full MI (since it would require adding components to
existing types, meaning that the components could not be assumed at a fixed
offset). That is a leap too far.
Note that in the OP's example, Janus/Ada does NOT treat the enclosing record
as controlled; each individual controlled object (including components) is
managed separately. I did it that way to make unwinding an object in the
face of exceptions during construction easier (each object is registered as
it is constructed, so all successfully constructed objects get finalized and
none that failed get finalized). GNAT, OTOH, does treat each object
individibly and has to go through some handstands so that objects that
aren't constructed aren't finalized.
Randy.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Controlled types as interfaces
2014-08-21 23:16 ` Randy Brukardt
@ 2014-08-29 15:01 ` Robert A Duff
2014-08-29 23:54 ` Randy Brukardt
0 siblings, 1 reply; 13+ messages in thread
From: Robert A Duff @ 2014-08-29 15:01 UTC (permalink / raw)
"Randy Brukardt" <randy@rrsoftware.com> writes:
> The real problem is that some (many?) implementations include
> implementation-defined components in types Controlled and
> Limited_Controlled. (For instance, Janus/Ada includes chain components.)
GNAT used to do that, but actually only heap objects need to be chained,
and the current implementation does not declare the chain links as
components. Controlled components and stack objects do not get
chained. A heap object is allocated with some extra space at negative
offsets, where the chain links are stored.
> Interfaces of course don't have any components; thus making
> Controlled/Limited_Controlled into interfaces would require the back-door
> implementation of full MI (since it would require adding components to
> existing types, meaning that the components could not be assumed at a fixed
> offset). That is a leap too far.
>
> Note that in the OP's example, Janus/Ada does NOT treat the enclosing record
> as controlled; each individual controlled object (including components) is
> managed separately. I did it that way to make unwinding an object in the
> face of exceptions during construction easier (each object is registered as
> it is constructed, so all successfully constructed objects get finalized and
> none that failed get finalized). GNAT, OTOH, does treat each object
^ not
> individibly and has to go through some handstands so that objects that
> aren't constructed aren't finalized.
I think you're missing a "not" there. Yes, there are some "handstands",
but it's not so bad. I think the only reason it was so hard to
implement is that it was a re-implementation. Doing it that way from
the start would not have been so bad (as is often the case).
The compiler generates a "deep_initialize" procedure for each type,
which either fully initializes everything, or else finalizes the parts
that got initialized before an exception.
Rational uses the same method as GNAT.
- Bob
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Controlled types as interfaces
2014-08-29 15:01 ` Robert A Duff
@ 2014-08-29 23:54 ` Randy Brukardt
0 siblings, 0 replies; 13+ messages in thread
From: Randy Brukardt @ 2014-08-29 23:54 UTC (permalink / raw)
"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message
news:wcc4mwv731x.fsf@shell01.TheWorld.com...
> "Randy Brukardt" <randy@rrsoftware.com> writes:
...
>> Note that in the OP's example, Janus/Ada does NOT treat the enclosing
>> record
>> as controlled; each individual controlled object (including components)
>> is
>> managed separately. I did it that way to make unwinding an object in the
>> face of exceptions during construction easier (each object is registered
>> as
>> it is constructed, so all successfully constructed objects get finalized
>> and
>> none that failed get finalized). GNAT, OTOH, does treat each object
> ^ not
>> individibly and has to go through some handstands so that objects that
>> aren't constructed aren't finalized.
>
> I think you're missing a "not" there.
I don't think so, but I don't claim to understand what GNAT does that well.
> Yes, there are some "handstands",
> but it's not so bad. I think the only reason it was so hard to
> implement is that it was a re-implementation. Doing it that way from
> the start would not have been so bad (as is often the case).
>
> The compiler generates a "deep_initialize" procedure for each type,
> which either fully initializes everything, or else finalizes the parts
> that got initialized before an exception.
Initialize routines like that are fiendishly complex (we do initializes that
way), especially because the combination of discriminant dependent
components and recursion to handle subcomponents. Trying to include
finalization in there would have caused madness, at a minimum when something
goes wrong. (They're literally impossible to debug, and I always find
something else to do rather than work on those routines. Sorry, Tero. :-)
Also, doing that requires that every call and check be effectively wrapped
with an exception handler since one has to know the exact point of failure.
For checks, that's not too bad as the check could be replaced by a branch.
But for calls, that can be expensive depending on the exception handling
scheme. (It's probably tractable for GNAT because of the zero-cost exception
handling, although that is clearly an additional source of complexity; for
Janus which uses a registration scheme, the cost would be way too expensive
to use regularly.)
As always with compiler construction, YMMV.
Randy.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2014-08-29 23:54 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-20 1:05 Controlled types as interfaces Victor Porton
2014-08-20 1:09 ` Victor Porton
2014-08-20 7:29 ` Dmitry A. Kazakov
2014-08-20 12:49 ` Victor Porton
2014-08-20 13:47 ` Dmitry A. Kazakov
2014-08-21 23:16 ` Randy Brukardt
2014-08-29 15:01 ` Robert A Duff
2014-08-29 23:54 ` Randy Brukardt
2014-08-20 12:50 ` Victor Porton
2014-08-20 13:38 ` Dmitry A. Kazakov
2014-08-20 13:56 ` Brad Moore
2014-08-21 22:48 ` Randy Brukardt
2014-08-20 1:41 ` Victor Porton
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox