comp.lang.ada
 help / color / mirror / Atom feed
* Limited_Controlled, orthogonality and related issues
@ 2007-01-18  9:24 Maciej Sobczak
  2007-01-18 12:00 ` Ludovic Brenta
                   ` (4 more replies)
  0 siblings, 5 replies; 22+ messages in thread
From: Maciej Sobczak @ 2007-01-18  9:24 UTC (permalink / raw)


Hi,

Consider the following problem:

package P is
    type T is limited private;
    type S is limited private;
    procedure Do_The_Job(X : in T; Y : in S);
    -- and gazillion of other subprograms like Do_The_Job
private
    -- ...
end P;

At some point I decide to add automatic destruction to T and S, so the 
package becomes:

with Ada.Finalization;
package P is
    type T is limited private;
    type S is limited private;
    procedure Do_The_Job(X : in T; Y : in S);
    -- and gazillion of other subprograms like Do_The_Job
private
    type T is new Ada.Finalization.Limited_Controlled with -- ...
    type S is new Ada.Finalization.Limited_Controlled with -- ...
end P;

Suddenly, the package no longer compiles:

"operation can be dispatching in only one type"

By making T and S controlled types, they became tagged and Do_The_Job is 
now incorrect.

First observation:
My design decision to make T and S controlled has absolutely nothing to 
do with Do_The_Job. It relates to those scopes where te objects are 
created, not to those where they are used. It looks that my decision 
affects unrelated parts of the pacakge (Do_The_Job and there are 
gazillions of such subprograms), which is non-sense. There is something 
wrong.

OK, I'm determined to get it done. I do this:

    procedure Do_The_Job(X : in T'Class; Y : in S'Class);

(one would be enough, but let's be symmetric)

Thanks to this, Do_The_Job is no longer dispatching (it was never 
supposed to be, by the way!).

But wait, now there's another problem:

"tagged type required"

It looks like the compiler pretends it doesn't know that T is tagged.

Second observation:
The compiler does know that T and S are tagged, because it is exactly 
what prevented it to compile Do_The_Job in its original form.
Now it pretends it has no idea that T and S are tagged, which is 
non-sense number two. Something's completely wrong here.

But I'm really determined to get it done. I do this:

    type T is tagged limited private;
    type S is tagged limited private;
    procedure Do_The_Job(X : in T'Class; Y : in S'Class);
    -- and gazillion of other subprograms like Do_The_Job

So, my simple decision to make T and S controlled required:

1. Changing the signatures of Do_The_Job and gazillion of similar 
subprograms.
2. Adding the tagged keyword in the public view for T and S.

In conclusion, my decision to make T and S controlled appeared to not be 
orthogonal to the rest of the package.

What are your thoughts about this?

Most importantly: why I had to add the tagged keyword?

-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-18  9:24 Limited_Controlled, orthogonality and related issues Maciej Sobczak
@ 2007-01-18 12:00 ` Ludovic Brenta
  2007-01-18 12:33   ` AW: " Grein, Christoph (Fa. ESG)
  2007-01-18 16:25   ` Robert A Duff
  2007-01-18 17:02 ` Adam Beneschan
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 22+ messages in thread
From: Ludovic Brenta @ 2007-01-18 12:00 UTC (permalink / raw)


Maciej Sobczak writes:
> Hi,
>
> Consider the following problem:
>
> package P is
>    type T is limited private;
>    type S is limited private;
>    procedure Do_The_Job(X : in T; Y : in S);
>    -- and gazillion of other subprograms like Do_The_Job
> private
>    -- ...
> end P;
>
> At some point I decide to add automatic destruction to T and S, so the
> package becomes:
>
> with Ada.Finalization;
> package P is
>    type T is limited private;
>    type S is limited private;
>    procedure Do_The_Job(X : in T; Y : in S);
>    -- and gazillion of other subprograms like Do_The_Job
> private
>    type T is new Ada.Finalization.Limited_Controlled with -- ...
>    type S is new Ada.Finalization.Limited_Controlled with -- ...
> end P;
>
> Suddenly, the package no longer compiles:
>
> "operation can be dispatching in only one type"
>
> By making T and S controlled types, they became tagged and Do_The_Job
> is now incorrect.
>
> First observation:
> My design decision to make T and S controlled has absolutely nothing
> to do with Do_The_Job. It relates to those scopes where te objects are
> created, not to those where they are used. It looks that my decision
> affects unrelated parts of the pacakge (Do_The_Job and there are
> gazillions of such subprograms), which is non-sense. There is
> something wrong.
>
> OK, I'm determined to get it done. I do this:
>
>    procedure Do_The_Job(X : in T'Class; Y : in S'Class);
>
> (one would be enough, but let's be symmetric)
>
> Thanks to this, Do_The_Job is no longer dispatching (it was never
> supposed to be, by the way!).
>
> But wait, now there's another problem:
>
> "tagged type required"
>
> It looks like the compiler pretends it doesn't know that T is tagged.
>
> Second observation:
> The compiler does know that T and S are tagged, because it is exactly
> what prevented it to compile Do_The_Job in its original form.
> Now it pretends it has no idea that T and S are tagged, which is
> non-sense number two. Something's completely wrong here.

The types are indeed not tagged in the public part of the package;
only the private part says they're tagged, and Do_The_Job, being
public, has to be consistent with the public declaration of the types.

> But I'm really determined to get it done. I do this:
>
>    type T is tagged limited private;
>    type S is tagged limited private;
>    procedure Do_The_Job(X : in T'Class; Y : in S'Class);
>    -- and gazillion of other subprograms like Do_The_Job
>
> So, my simple decision to make T and S controlled required:
>
> 1. Changing the signatures of Do_The_Job and gazillion of similar
> subprograms.
> 2. Adding the tagged keyword in the public view for T and S.
>
> In conclusion, my decision to make T and S controlled appeared to not
> be orthogonal to the rest of the package.
>
> What are your thoughts about this?

I would have used a mix-in, like so:

with Ada.Finalization;
package P is
   type T is limited private;
   type S is limited private;
   procedure Do_The_Job(X : in T; Y : in S);
   -- and gazillion of other subprograms like Do_The_Job
private
   type T_Finalizer (Enclosing : access T) is
     new Ada.Finalization.Limited_Controlled with null record;

   procedure Finalize (Finalizer : in out T);

   type S_Finalizer (Enclosing : access S) is
     new Ada.Finalization.Limited_Controlled with null record;

   procedure Finalize (Finalizer : in out S);

   type T is record
      -- other components
      Finalizer : T_Finalizer (T'Access);
   end record;

   type S is record
      -- other components
      Finalizer : S_Finalizer (S'Access);
   end record;
end P;

with Ada.Text_IO;
package body P is
   procedure Do_The_Job(X : in T; Y : in S) is
   begin
      Ada.Text_IO.Put_Line ("Doing the job.");
   end Do_The_Job;

   procedure Finalize (Finalizer : in out T) is
   begin
      Ada.Text_IO.Put_Line ("Finalizing a T.");
   end Finalize;


   procedure Finalize (Finalizer : in out S) is
   begin
      Ada.Text_IO.Put_Line ("Finalizing a S.");
   end Finalize;
end P;

with P;
procedure Test is
   My_T : P.T;
   My_S : P.S;
begin
   P.Do_The_Job (My_T, My_S);
end Test;

but the program compiled with GNAT does not display the two
finalization messages.  Bug (i.e. the finalization procedures should
be called as per ARM 7.6.1(9)) or feature (i.e. GNAT optimizes the
calls away, noticing that the program is terminating anyway)?

> Most importantly: why I had to add the tagged keyword?

Because Do_The_Job required the types to be publicly tagged.

-- 
Ludovic Brenta.



^ permalink raw reply	[flat|nested] 22+ messages in thread

* AW: Limited_Controlled, orthogonality and related issues
  2007-01-18 12:00 ` Ludovic Brenta
@ 2007-01-18 12:33   ` Grein, Christoph (Fa. ESG)
  2007-01-18 16:25   ` Robert A Duff
  1 sibling, 0 replies; 22+ messages in thread
From: Grein, Christoph (Fa. ESG) @ 2007-01-18 12:33 UTC (permalink / raw)
  To: comp.lang.ada

private with Ada.Finalization;     --*

package P is

   type T is limited private;
   type S is limited private;

   procedure Do_The_Job(X : in T; Y : in S);

private

   type T_Finalizer (Enclosing : access T) is
     new Ada.Finalization.Limited_Controlled with null record;
   overriding                                                  --*
   procedure Finalize (Finalizer : in out T_Finalizer);        --*

   type S_Finalizer (Enclosing : access S) is
     new Ada.Finalization.Limited_Controlled with null record;
   overriding                                                  --*
   procedure Finalize (Finalizer : in out S_Finalizer);        --*

   type T is record
      -- other components
      Finalizer : T_Finalizer (T'Access);
   end record;

   type S is record
      -- other components
      Finalizer : S_Finalizer (S'Access);
   end record;
end P;

Had you used the new overriding keyword, you has seen the mistake.
Changes marked by --*. With this, the finalizers are called.



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-18 12:00 ` Ludovic Brenta
  2007-01-18 12:33   ` AW: " Grein, Christoph (Fa. ESG)
@ 2007-01-18 16:25   ` Robert A Duff
  1 sibling, 0 replies; 22+ messages in thread
From: Robert A Duff @ 2007-01-18 16:25 UTC (permalink / raw)


Ludovic Brenta <ludovic@ludovic-brenta.org> writes:

>    type T_Finalizer (Enclosing : access T) is
>      new Ada.Finalization.Limited_Controlled with null record;
>
>    procedure Finalize (Finalizer : in out T);

> but the program compiled with GNAT does not display the two
> finalization messages.  Bug (i.e. the finalization procedures should
> be called as per ARM 7.6.1(9)) or feature (i.e. GNAT optimizes the
> calls away, noticing that the program is terminating anyway)?

Bug -- in your program.  ;-)

You meant T_Finalizer instead of T in procedure Finalize.  This is an
easy mistake to make.  As somebody pointed out, in Ada 2005, you can use
the overriding keyword to prevent that problem.

- Bob



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-18  9:24 Limited_Controlled, orthogonality and related issues Maciej Sobczak
  2007-01-18 12:00 ` Ludovic Brenta
@ 2007-01-18 17:02 ` Adam Beneschan
  2007-01-18 17:16   ` Adam Beneschan
                     ` (2 more replies)
  2007-01-18 19:03 ` Jeffrey Carter
                   ` (2 subsequent siblings)
  4 siblings, 3 replies; 22+ messages in thread
From: Adam Beneschan @ 2007-01-18 17:02 UTC (permalink / raw)


Maciej Sobczak wrote:
> Hi,
>
> Consider the following problem:
>
> package P is
>     type T is limited private;
>     type S is limited private;
>     procedure Do_The_Job(X : in T; Y : in S);
>     -- and gazillion of other subprograms like Do_The_Job
> private
>     -- ...
> end P;
>
> At some point I decide to add automatic destruction to T and S, so the
> package becomes:
>
> with Ada.Finalization;
> package P is
>     type T is limited private;
>     type S is limited private;
>     procedure Do_The_Job(X : in T; Y : in S);
>     -- and gazillion of other subprograms like Do_The_Job
> private
>     type T is new Ada.Finalization.Limited_Controlled with -- ...
>     type S is new Ada.Finalization.Limited_Controlled with -- ...
> end P;
>
> Suddenly, the package no longer compiles:
>
> "operation can be dispatching in only one type"
>
> By making T and S controlled types, they became tagged and Do_The_Job is
> now incorrect.

On looking at this, I wonder if this was an error in the design of Ada
95.  Primitive operations of tagged types are dispatching, and the
reason is that so that another package can declare a type extension
from a tagged type and inherit the dispatching operation, and possibly
override it, and then somebody could use the operation on a class-wide
type to call the correct operation for that particular object, and thus
achieve polymorphism.  But when  the partial view of a type is not
tagged, then other packages can't derive type extensions from it and
can't apply 'Class to it, so was there any logical reason why an
operation on that type (declared in the visible part of the package)
should be dispatching?  Maybe not, since the dispatch could "almost
never" take place in practice, and since making the operation
dispatching adds restrictions just like the one Maciej found.

I say "almost never" because in theory, since the private part or body
of P or of a child of P (or the visible part of a private child of P)
*could* derive a type extension from the tagged type and dispatch.  But
I'd guess that such usage would be rare.

So it seems to me that (1) it would have been better to say in 3.9.2
that a primitive operation of an untagged private type whose full view
is tagged is not dispatching, at least if the operation is declared in
the visible part of the package; or (2) some way should have been
provided for the programmer to specify that an operation that 3.9.2
defines as "dispatching" really isn't.

Maybe (2) is still possible.  I'm guessing that it's way too late to
make (1) the rule.  So this is probably really just a useless rant.

Has this issue been discussed somewhere else, by the way?

                           -- Adam




^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-18 17:02 ` Adam Beneschan
@ 2007-01-18 17:16   ` Adam Beneschan
  2007-01-19  1:02     ` Robert A Duff
  2007-01-19  9:05     ` Dmitry A. Kazakov
  2007-01-19  1:01   ` Robert A Duff
  2007-01-19  9:57   ` Stephen Leake
  2 siblings, 2 replies; 22+ messages in thread
From: Adam Beneschan @ 2007-01-18 17:16 UTC (permalink / raw)


Adam Beneschan ranted uselessly:

> On looking at this, I wonder if this was an error in the design of Ada
> 95.  Primitive operations of tagged types are dispatching, and the
> reason is that so that another package can declare a type extension
> from a tagged type and inherit the dispatching operation, and possibly
> override it, and then somebody could use the operation on a class-wide
> type to call the correct operation for that particular object, and thus
> achieve polymorphism.  But when  the partial view of a type is not
> tagged, then other packages can't derive type extensions from it and
> can't apply 'Class to it, so was there any logical reason why an
> operation on that type (declared in the visible part of the package)
> should be dispatching?  Maybe not, since the dispatch could "almost
> never" take place in practice, and since making the operation
> dispatching adds restrictions just like the one Maciej found.
>
> I say "almost never" because in theory, since the private part or body
> of P or of a child of P (or the visible part of a private child of P)
> *could* derive a type extension from the tagged type and dispatch.  But
> I'd guess that such usage would be rare.
>
> So it seems to me that (1) it would have been better to say in 3.9.2
> that a primitive operation of an untagged private type whose full view
> is tagged is not dispatching, at least if the operation is declared in
> the visible part of the package; or (2) some way should have been
> provided for the programmer to specify that an operation that 3.9.2
> defines as "dispatching" really isn't.
>
> Maybe (2) is still possible.  I'm guessing that it's way too late to
> make (1) the rule.  So this is probably really just a useless rant.

On reflection, maybe there *is* a way to fix this: Change the first
sentence of 3.9.2(1) to read, "The primitive subprograms of a tagged
type are called dispatching operations, except that a primitive
subprogram of two or more tagged types is not a dispatching operation
if it is declared in the visible part of a package, and every type of
which the subprogram is a primitive operation is an untagged type or a
tagged type whose partial view is untagged".  Or something along those
lines.  The idea is that a change like this would have no effect on
programs that are currently legal, so it seems like it should be safe.
And it would make programs like Maciej's original attempt legal, as
they (IMHO) should be.

                               -- Adam




^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-18  9:24 Limited_Controlled, orthogonality and related issues Maciej Sobczak
  2007-01-18 12:00 ` Ludovic Brenta
  2007-01-18 17:02 ` Adam Beneschan
@ 2007-01-18 19:03 ` Jeffrey Carter
  2007-01-19  7:48 ` Randy Brukardt
  2007-01-19 15:29 ` Robert A Duff
  4 siblings, 0 replies; 22+ messages in thread
From: Jeffrey Carter @ 2007-01-18 19:03 UTC (permalink / raw)


Maciej Sobczak wrote:
> 
> What are your thoughts about this?

This is a consequence of the decision to make finalization an attribute 
of type extension (from "magic" types in Ada.Finalization), rather than 
a separate language feature.



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-18 17:02 ` Adam Beneschan
  2007-01-18 17:16   ` Adam Beneschan
@ 2007-01-19  1:01   ` Robert A Duff
  2007-01-19  9:57   ` Stephen Leake
  2 siblings, 0 replies; 22+ messages in thread
From: Robert A Duff @ 2007-01-19  1:01 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> writes:

> I say "almost never" because in theory, since the private part or body
> of P or of a child of P (or the visible part of a private child of P)
> *could* derive a type extension from the tagged type and dispatch.  But
> I'd guess that such usage would be rare.

I think it's quite common for a child package to extend types in the
parent package, and override operations.

- Bob



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-18 17:16   ` Adam Beneschan
@ 2007-01-19  1:02     ` Robert A Duff
  2007-01-19  7:38       ` Maciej Sobczak
  2007-01-19  9:05     ` Dmitry A. Kazakov
  1 sibling, 1 reply; 22+ messages in thread
From: Robert A Duff @ 2007-01-19  1:02 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> writes:

> On reflection, maybe there *is* a way to fix this: Change the first
> sentence of 3.9.2(1) to read, "The primitive subprograms of a tagged
> type are called dispatching operations, except that a primitive
> subprogram of two or more tagged types is not a dispatching operation
> if it is declared in the visible part of a package, and every type of
> which the subprogram is a primitive operation is an untagged type or a
> tagged type whose partial view is untagged".  Or something along those
> lines.  The idea is that a change like this would have no effect on
> programs that are currently legal, so it seems like it should be safe.
> And it would make programs like Maciej's original attempt legal, as
> they (IMHO) should be.

Might work, I'm not sure.  Is this really a big problem that needs
fixing?

- Bob



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-19  1:02     ` Robert A Duff
@ 2007-01-19  7:38       ` Maciej Sobczak
  0 siblings, 0 replies; 22+ messages in thread
From: Maciej Sobczak @ 2007-01-19  7:38 UTC (permalink / raw)


Robert A Duff wrote:

> Is this really a big problem that needs
> fixing?

It depends on the viewpoint.
You might argue that adding a limited controlled property to the type 
should have been foreseen from the very beginning, not as an 
afterthought, and the experienced Ada developer should know that such 
types are tagged so that all operations can be written appropriately 
(ie. to use class-wide parameters) from the outset. But I would say that 
this is just "gotcha" - something that can scare off newcomers.

It's hard to "fix" (whatever that means) - destructors should have been 
part of the object model from the very beginning.


-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-18  9:24 Limited_Controlled, orthogonality and related issues Maciej Sobczak
                   ` (2 preceding siblings ...)
  2007-01-18 19:03 ` Jeffrey Carter
@ 2007-01-19  7:48 ` Randy Brukardt
  2007-01-19 16:46   ` Adam Beneschan
  2007-01-19 15:29 ` Robert A Duff
  4 siblings, 1 reply; 22+ messages in thread
From: Randy Brukardt @ 2007-01-19  7:48 UTC (permalink / raw)


"Maciej Sobczak" <no.spam@no.spam.com> wrote in message
news:eoned5$663$1@cernne03.cern.ch...
...
> In conclusion, my decision to make T and S controlled appeared to not be
> orthogonal to the rest of the package.
>
> What are your thoughts about this?

It's dubious to have two abstractions in the same package. It's a nice
simplification compared to other languages, but it's usually better to have
fewer types in one package rather than more. If T and S were in different
packages, this problem wouldn't happen. Note that one of the packages could
be nested or a child, and that would still have the visibility on the
private part.

Something like:

package Root is
   type S is limited private;
...
end Root;

package Root.Child is
   type T is limited private;
   procedure Do_Something (A : T, B : S);
...
end Root.Child;

Usually, one or the other of the abstractions can be used alone, and that is
the one that belongs in the root.

                    Randy.





^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-18 17:16   ` Adam Beneschan
  2007-01-19  1:02     ` Robert A Duff
@ 2007-01-19  9:05     ` Dmitry A. Kazakov
  2007-01-19 17:04       ` Adam Beneschan
  1 sibling, 1 reply; 22+ messages in thread
From: Dmitry A. Kazakov @ 2007-01-19  9:05 UTC (permalink / raw)


On 18 Jan 2007 09:16:22 -0800, Adam Beneschan wrote:

> Adam Beneschan ranted uselessly:
> 
>> On looking at this, I wonder if this was an error in the design of Ada
>> 95.  Primitive operations of tagged types are dispatching, and the
>> reason is that so that another package can declare a type extension
>> from a tagged type and inherit the dispatching operation, and possibly
>> override it, and then somebody could use the operation on a class-wide
>> type to call the correct operation for that particular object, and thus
>> achieve polymorphism.  But when  the partial view of a type is not
>> tagged, then other packages can't derive type extensions from it and
>> can't apply 'Class to it, so was there any logical reason why an
>> operation on that type (declared in the visible part of the package)
>> should be dispatching?  Maybe not, since the dispatch could "almost
>> never" take place in practice, and since making the operation
>> dispatching adds restrictions just like the one Maciej found.
>>
>> I say "almost never" because in theory, since the private part or body
>> of P or of a child of P (or the visible part of a private child of P)
>> *could* derive a type extension from the tagged type and dispatch.  But
>> I'd guess that such usage would be rare.
>>
>> So it seems to me that (1) it would have been better to say in 3.9.2
>> that a primitive operation of an untagged private type whose full view
>> is tagged is not dispatching, at least if the operation is declared in
>> the visible part of the package; or (2) some way should have been
>> provided for the programmer to specify that an operation that 3.9.2
>> defines as "dispatching" really isn't.
>>
>> Maybe (2) is still possible.  I'm guessing that it's way too late to
>> make (1) the rule.  So this is probably really just a useless rant.
> 
> On reflection, maybe there *is* a way to fix this: Change the first
> sentence of 3.9.2(1) to read, "The primitive subprograms of a tagged
> type are called dispatching operations, except that a primitive
> subprogram of two or more tagged types is not a dispatching operation
> if it is declared in the visible part of a package, and every type of
> which the subprogram is a primitive operation is an untagged type or a
> tagged type whose partial view is untagged".  Or something along those
> lines.  The idea is that a change like this would have no effect on
> programs that are currently legal, so it seems like it should be safe.
> And it would make programs like Maciej's original attempt legal, as
> they (IMHO) should be.

I think that this idea is wrong because it fixes broken public view
[non-tagged but dispatching], by breaking the private view [non-dispatching
but tagged]. I think that the guiding rule should be that all views of the
same thing shall be consistent. For this reason it would be better that for
such subprograms the private view of such subprograms were class-wide:

package
   type T is limited private;
   procedure Foo (X : in out T);
private
   type T is new Ada.Finalization.Limited_Controlled with ...;
--
-- Here Foo is seen as
--
--    procedure Foo (X : in out T'Class);

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-18 17:02 ` Adam Beneschan
  2007-01-18 17:16   ` Adam Beneschan
  2007-01-19  1:01   ` Robert A Duff
@ 2007-01-19  9:57   ` Stephen Leake
  2 siblings, 0 replies; 22+ messages in thread
From: Stephen Leake @ 2007-01-19  9:57 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> writes:

> I say "almost never" because in theory, since the private part or body
> of P or of a child of P (or the visible part of a private child of P)
> *could* derive a type extension from the tagged type and dispatch.  But
> I'd guess that such usage would be rare.

Not "rare"; I have several programs that do just that :).

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-18  9:24 Limited_Controlled, orthogonality and related issues Maciej Sobczak
                   ` (3 preceding siblings ...)
  2007-01-19  7:48 ` Randy Brukardt
@ 2007-01-19 15:29 ` Robert A Duff
  2007-01-19 16:31   ` Dmitry A. Kazakov
  4 siblings, 1 reply; 22+ messages in thread
From: Robert A Duff @ 2007-01-19 15:29 UTC (permalink / raw)


Maciej Sobczak <no.spam@no.spam.com> writes:

> So, my simple decision to make T and S controlled required:
>
> 1. Changing the signatures of Do_The_Job and gazillion of similar
> subprograms.
> 2. Adding the tagged keyword in the public view for T and S.
>
> In conclusion, my decision to make T and S controlled appeared to not be
> orthogonal to the rest of the package.

I really can't get too excited about the fact that a change to the
package required other changes to the same package.  If you said
that clients had to change, that would be a much bigger problem.

Possible solutions:

Allow 'Class on untagged types.

Use special syntax to distinguish dispatching operations.

Make all types tagged.  For efficiency, this would require a different
run-time model than what Ada compilers currently do -- you don't want
to store a tag field with every Boolean variable!  To enable the
non-stored-tag model, eliminate the rule that all tagged parameter
are aliased (and allow "aliased" keyword).

None of the above are likely to happen, I suspect.

- Bob



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-19 15:29 ` Robert A Duff
@ 2007-01-19 16:31   ` Dmitry A. Kazakov
  2007-01-19 16:36     ` Robert A Duff
  0 siblings, 1 reply; 22+ messages in thread
From: Dmitry A. Kazakov @ 2007-01-19 16:31 UTC (permalink / raw)


On Fri, 19 Jan 2007 10:29:35 -0500, Robert A Duff wrote:

> Make all types tagged.  For efficiency, this would require a different
> run-time model than what Ada compilers currently do -- you don't want
> to store a tag field with every Boolean variable!  To enable the
> non-stored-tag model, eliminate the rule that all tagged parameter
> are aliased (and allow "aliased" keyword).
> 
> None of the above are likely to happen, I suspect.

Even if we, all the Ada community, really wanted it? 

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-19 16:31   ` Dmitry A. Kazakov
@ 2007-01-19 16:36     ` Robert A Duff
  2007-01-19 18:26       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 22+ messages in thread
From: Robert A Duff @ 2007-01-19 16:36 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On Fri, 19 Jan 2007 10:29:35 -0500, Robert A Duff wrote:
>
>> Make all types tagged.  For efficiency, this would require a different
>> run-time model than what Ada compilers currently do -- you don't want
>> to store a tag field with every Boolean variable!  To enable the
>> non-stored-tag model, eliminate the rule that all tagged parameter
>> are aliased (and allow "aliased" keyword).
>> 
>> None of the above are likely to happen, I suspect.
>
> Even if we, all the Ada community, really wanted it? 

The Ada community wants compatibility with older versions of the
language.  What I described above is not compatible.

- Bob



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-19  7:48 ` Randy Brukardt
@ 2007-01-19 16:46   ` Adam Beneschan
  0 siblings, 0 replies; 22+ messages in thread
From: Adam Beneschan @ 2007-01-19 16:46 UTC (permalink / raw)


Randy Brukardt wrote:
> "Maciej Sobczak" <no.spam@no.spam.com> wrote in message
> news:eoned5$663$1@cernne03.cern.ch...
> ...
> > In conclusion, my decision to make T and S controlled appeared to not be
> > orthogonal to the rest of the package.
> >
> > What are your thoughts about this?
>
> It's dubious to have two abstractions in the same package. It's a nice
> simplification compared to other languages, but it's usually better to have
> fewer types in one package rather than more. If T and S were in different
> packages, this problem wouldn't happen. Note that one of the packages could
> be nested or a child, and that would still have the visibility on the
> private part.
>
> Something like:
>
> package Root is
>    type S is limited private;
> ...
> end Root;
>
> package Root.Child is
>    type T is limited private;
>    procedure Do_Something (A : T, B : S);
> ...
> end Root.Child;

Yep, I hadn't thought of that.  And if you use nested inside of child
packages, you could do something like this:

package Root is
    type S is limited private;
    package Inner is
         type T is limited private;
    end Inner;
    subtype T is Inner.T;
    procedure Do_Something (A : T; B : S);
    ...

Now Do_Something isn't a primitive operator on T so there's no 3.9.2
error.  Whether this is "appropriate" or not, I can't tell without
knowing more about the exact types and operations involved.  For the
examples I can think of that I've worked with, S might be some sort of
container type, T might be an iterator to help search through selected
objects in S, and Do_Something might be a routine that returns
successive elements of S that meet some criteria.  In a case like that,
Do_Something probably "belongs" inside the Inner package.  But there
are probably other cases where you would prefer to have Do_Something
outside the Inner package.  It's hard to say without knowing any
details.  But the point is, you can use a construct like this to avoid
the "multiple dispatch" error, and this solution will still let you
implement S and T any way you want in the private part---as opposed to
making S and T part of the same package which prevents you from
implementing both of them as tagged types.

                              -- Adam




^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-19  9:05     ` Dmitry A. Kazakov
@ 2007-01-19 17:04       ` Adam Beneschan
  0 siblings, 0 replies; 22+ messages in thread
From: Adam Beneschan @ 2007-01-19 17:04 UTC (permalink / raw)


Dmitry A. Kazakov wrote:

> > On reflection, maybe there *is* a way to fix this: Change the first
> > sentence of 3.9.2(1) to read, "The primitive subprograms of a tagged
> > type are called dispatching operations, except that a primitive
> > subprogram of two or more tagged types is not a dispatching operation
> > if it is declared in the visible part of a package, and every type of
> > which the subprogram is a primitive operation is an untagged type or a
> > tagged type whose partial view is untagged".  Or something along those
> > lines.  The idea is that a change like this would have no effect on
> > programs that are currently legal, so it seems like it should be safe.
> > And it would make programs like Maciej's original attempt legal, as
> > they (IMHO) should be.
>
> I think that this idea is wrong because it fixes broken public view
> [non-tagged but dispatching], by breaking the private view [non-dispatching
> but tagged].

It's certainly a "hack" solution that would introduce an inconsistency
into the language, but that certainly wouldn't be the first time
something inconsistent was added to Ada, in order to try to fix a
problem while having minimal effect on existing programs.  Unless I've
missed something, the hack solution I proposed would affect *only*
programs that are currently illegal while having no effect on the
semantics of currently legal programs, so from that standpoint I don't
see how it "breaks" anything.

However, now that I've seen Randy's post, I'm convinced that there are
less onerous ways to get around the problem---you can arrange things so
that you can declare this subprogram and still implement the full views
of the types any way you wish.  So there's probably less of a reason to
add a "hack" like this to the language than there was when I first
posted it.

I think that your idea below is possibly a good reflection of how
things *should* have been designed, in theory; but I think it could
break existing programs if we tried to add that now.  I'm afraid that
not enough consideration was given to the special problems of untagged
private types whose full view is tagged when Ada 95 was designed; as I
recall, I've found areas of the RM that were worded in a way that made
it unclear what should happen with such types.

                                -- Adam


> I think that the guiding rule should be that all views of the
> same thing shall be consistent. For this reason it would be better that for
> such subprograms the private view of such subprograms were class-wide:
>
> package
>    type T is limited private;
>    procedure Foo (X : in out T);
> private
>    type T is new Ada.Finalization.Limited_Controlled with ...;
> --
> -- Here Foo is seen as
> --
> --    procedure Foo (X : in out T'Class);




^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-19 16:36     ` Robert A Duff
@ 2007-01-19 18:26       ` Dmitry A. Kazakov
  2007-01-19 20:17         ` Robert A Duff
  0 siblings, 1 reply; 22+ messages in thread
From: Dmitry A. Kazakov @ 2007-01-19 18:26 UTC (permalink / raw)


On Fri, 19 Jan 2007 11:36:57 -0500, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> On Fri, 19 Jan 2007 10:29:35 -0500, Robert A Duff wrote:
>>
>>> Make all types tagged.  For efficiency, this would require a different
>>> run-time model than what Ada compilers currently do -- you don't want
>>> to store a tag field with every Boolean variable!  To enable the
>>> non-stored-tag model, eliminate the rule that all tagged parameter
>>> are aliased (and allow "aliased" keyword).
>>> 
>>> None of the above are likely to happen, I suspect.
>>
>> Even if we, all the Ada community, really wanted it? 
> 
> The Ada community wants compatibility with older versions of the
> language.  What I described above is not compatible.

I don't directly see what and why.

We could make all types "tagged" with non-stored tags. The keyword "tagged"
would mean a stored tag + by-reference semantics. This looks fully backward
compatible to me, at first glance.

As for legacy exceptions, we should choose a model first. Is End_Error a
type (derived from Root_Exception) or a value of Root_Exception?

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-19 18:26       ` Dmitry A. Kazakov
@ 2007-01-19 20:17         ` Robert A Duff
  2007-01-20 10:14           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 22+ messages in thread
From: Robert A Duff @ 2007-01-19 20:17 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On Fri, 19 Jan 2007 11:36:57 -0500, Robert A Duff wrote:
>
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>> 
>>> On Fri, 19 Jan 2007 10:29:35 -0500, Robert A Duff wrote:
>>>
>>>> Make all types tagged.  For efficiency, this would require a different
>>>> run-time model than what Ada compilers currently do -- you don't want
>>>> to store a tag field with every Boolean variable!  To enable the
>>>> non-stored-tag model, eliminate the rule that all tagged parameter
>>>> are aliased (and allow "aliased" keyword).
>>>> 
>>>> None of the above are likely to happen, I suspect.
>>>
>>> Even if we, all the Ada community, really wanted it? 
>> 
>> The Ada community wants compatibility with older versions of the
>> language.  What I described above is not compatible.
>
> I don't directly see what and why.

I meant that if all types are tagged, then we should remove the "tagged"
keyword from the language (obviously incompatible) and eliminate the
"all tagged parameters are aliased" rule (incompatible).  Oh, by the
way, eliminate "tagged types are pass-by-ref" (incompatible).

> We could make all types "tagged" with non-stored tags. The keyword "tagged"
> would mean a stored tag + by-reference semantics. This looks fully backward
> compatible to me, at first glance.

OK, that might work.  I don't see anything fundamentally wrong with it
"at first glance".  ;-)  I suppose abstract subprograms would cause
minor troubles...

Perhaps you should push for this in Ada 2015 or 2025.  ;-)

> As for legacy exceptions, we should choose a model first. Is End_Error a
> type (derived from Root_Exception) or a value of Root_Exception?

End_Error should be a type (in this fantasy version of Ada).

- Bob



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-19 20:17         ` Robert A Duff
@ 2007-01-20 10:14           ` Dmitry A. Kazakov
  2007-01-20 14:44             ` Robert A Duff
  0 siblings, 1 reply; 22+ messages in thread
From: Dmitry A. Kazakov @ 2007-01-20 10:14 UTC (permalink / raw)


On Fri, 19 Jan 2007 15:17:04 -0500, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> On Fri, 19 Jan 2007 11:36:57 -0500, Robert A Duff wrote:
>>
>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>> 
>> We could make all types "tagged" with non-stored tags. The keyword "tagged"
>> would mean a stored tag + by-reference semantics. This looks fully backward
>> compatible to me, at first glance.
> 
> OK, that might work.  I don't see anything fundamentally wrong with it
> "at first glance".  ;-)  I suppose abstract subprograms would cause
> minor troubles...
> 
> Perhaps you should push for this in Ada 2015 or 2025.  ;-)

I am pushing for it all the time!.. (:-))

>> As for legacy exceptions, we should choose a model first. Is End_Error a
>> type (derived from Root_Exception) or a value of Root_Exception?
> 
> End_Error should be a type (in this fantasy version of Ada).

Then we have the first problem. Types cannot be renamed in Ada. Exceptions
can be.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Limited_Controlled, orthogonality and related issues
  2007-01-20 10:14           ` Dmitry A. Kazakov
@ 2007-01-20 14:44             ` Robert A Duff
  0 siblings, 0 replies; 22+ messages in thread
From: Robert A Duff @ 2007-01-20 14:44 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On Fri, 19 Jan 2007 15:17:04 -0500, Robert A Duff wrote:
>> End_Error should be a type (in this fantasy version of Ada).
>
> Then we have the first problem. Types cannot be renamed in Ada. Exceptions
> can be.

Indeed.  Designing a feature is relatively straightforward.
Making it upward compatible is really hard.

- Bob



^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2007-01-20 14:44 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-01-18  9:24 Limited_Controlled, orthogonality and related issues Maciej Sobczak
2007-01-18 12:00 ` Ludovic Brenta
2007-01-18 12:33   ` AW: " Grein, Christoph (Fa. ESG)
2007-01-18 16:25   ` Robert A Duff
2007-01-18 17:02 ` Adam Beneschan
2007-01-18 17:16   ` Adam Beneschan
2007-01-19  1:02     ` Robert A Duff
2007-01-19  7:38       ` Maciej Sobczak
2007-01-19  9:05     ` Dmitry A. Kazakov
2007-01-19 17:04       ` Adam Beneschan
2007-01-19  1:01   ` Robert A Duff
2007-01-19  9:57   ` Stephen Leake
2007-01-18 19:03 ` Jeffrey Carter
2007-01-19  7:48 ` Randy Brukardt
2007-01-19 16:46   ` Adam Beneschan
2007-01-19 15:29 ` Robert A Duff
2007-01-19 16:31   ` Dmitry A. Kazakov
2007-01-19 16:36     ` Robert A Duff
2007-01-19 18:26       ` Dmitry A. Kazakov
2007-01-19 20:17         ` Robert A Duff
2007-01-20 10:14           ` Dmitry A. Kazakov
2007-01-20 14:44             ` Robert A Duff

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox