comp.lang.ada
 help / color / mirror / Atom feed
* Re: generic formal primitive [dispatching] operation
       [not found] <39C5321E.805A73D1@free.fr>
@ 2000-09-18  0:00 ` Thomas Quinot
  2000-09-19  0:00   ` Damien Carbonne
  2000-09-18  0:00 ` Robert A Duff
  1 sibling, 1 reply; 5+ messages in thread
From: Thomas Quinot @ 2000-09-18  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 801 bytes --]

Dans comp.lang.ada, Damien Carbonne  �crit :

>I would like to create a generic package that has, as formal parameters,
>a tagged type and some primitive dispatching operations on that type.
>
>I have tried this:
>
>generic
>   type Root is abstract tagged private;
>   with procedure P1 (This : access Root);

P1 is not a primitive operation of Root, because in instances of your
package, P1 denotes a view of the actual parameter, and does not
declare a subprogram. The subprogram denoted by P1 is thus not
declared in the same declarative_region as type Root, and therefore
does not qualify to be a primitive operation of Root.

It is unclear to me what you are trying to achieve. Could you be more
specific about what you actually want to do?

Thomas.

-- 
    Thomas.Quinot@Cuivre.FR.EU.ORG




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

* Re: generic formal primitive [dispatching] operation
       [not found] <39C5321E.805A73D1@free.fr>
  2000-09-18  0:00 ` generic formal primitive [dispatching] operation Thomas Quinot
@ 2000-09-18  0:00 ` Robert A Duff
  2000-09-19  0:00   ` Damien Carbonne
  1 sibling, 1 reply; 5+ messages in thread
From: Robert A Duff @ 2000-09-18  0:00 UTC (permalink / raw)


Damien Carbonne <damien.carbonne@free.fr> writes:

> I would like to create a generic package that has, as formal parameters,
> a tagged type and some primitive dispatching operations on that type.

Try using a generic formal derived type.  Declare the root type outside
the generic, with the primitive you want, and then declare a generic
formal type derived from that.

> 1) How is it possible to define a formal primitive operation on a tagged
> type that is:
>    a) non dispatching (Root'Class ??)

Primitive = dispatching (for tagged types).  Class-wide types are not
primitive.

>    b) dispatching

See above.

> 2) In the case of class-wide operations, is there any difference between
> primitive and non primitive
>    operations ? (I would say no ?)

A class-wide operation is *not* primitive.

- Bob




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

* Re: generic formal primitive [dispatching] operation
  2000-09-18  0:00 ` generic formal primitive [dispatching] operation Thomas Quinot
@ 2000-09-19  0:00   ` Damien Carbonne
  0 siblings, 0 replies; 5+ messages in thread
From: Damien Carbonne @ 2000-09-19  0:00 UTC (permalink / raw)


Thomas Quinot a �crit :

> Dans comp.lang.ada, Damien Carbonne  �crit :
>
> >I would like to create a generic package that has, as formal parameters,
> >a tagged type and some primitive dispatching operations on that type.
> >
> >I have tried this:
> >
> >generic
> >   type Root is abstract tagged private;
> >   with procedure P1 (This : access Root);
>
> P1 is not a primitive operation of Root, because in instances of your
> package, P1 denotes a view of the actual parameter, and does not
> declare a subprogram. The subprogram denoted by P1 is thus not
> declared in the same declarative_region as type Root, and therefore
> does not qualify to be a primitive operation of Root.
>
> It is unclear to me what you are trying to achieve. Could you be more
> specific about what you actually want to do?

Right, I will try to give a better description of the problem I have, and
why I created the example I gave previously.

I would like to create a package that looks like that:

-- generic_reference.ads
-------------------------------------------------------------------------------------------

with Ada.Finalization; use Ada.Finalization;

generic
   type Transformation is private;
   with function Identity return Transformation is <>;
   with function "*" (Left, Rigth : Transformation) return Transformation is
<>;

   type Transformer is abstract tagged limited private;
   -- Here I believe that these decalaration can match primitive operations
of Transformer
   with function Parent_To_Self (This : access Transformer) return
Transformation is <>;
   with function Self_To_Parent (This : access Transformer) return
Transformation is <>;
package Generic_References is

   pragma Elaborate_Body;

   type Transformer_Ref is access all Transformer'Class;

   type Reference is limited private;
   type Reference_Ptr is access all Reference;

   procedure Set_Parent
     (This   : access Reference;
      Parent : in     Reference_Ptr);

   procedure Set_Transformer
     (This        : access Reference;
      Transformer : in     Transformer_Ref);

   function Transformation_Betweeen
     (Ref_1 : access Reference;
      Ref_2 : access Reference)
      return Transformation;

private

   -- Here I want to derive Root and redefine dispatching operations.
   type Identity_Transformer is new Transformer with null record;
   function Parent_To_Self (This : access Identity_Transformer) return
Transformation;
   function Self_To_Parent (This : access Identity_Transformer) return
Transformation;

   G_Identity_Transformer : Transformer_Ref := new Identity_Transformer;

   type Reference is new Limited_Controlled with record
      null;
   end record;

   procedure Initialize (Obj : in out Reference);
   procedure Finalize   (Obj : in out Reference);

end Generic_References;
-------------------------------------------------------------------------------------------

The objective is to handle the notion of Reference attached to a body, and
to provide a simple
way to make any location or velocity or acceleration etc ...changes between
two any references.

From this package point of view, a Transformation must only have two
operations:
1) composition
2) Identity

Such a Transformation can be imagined in any Space (2D, 3D, etc) or anything
else that has no direct
geometric interpretation.

The Transformer type must be viewed as a java-like interface. Its role is to
provide the
transformations between two References (via Parent_To_Self and
Self_To_Parent).

Initially I had not declared Identity_Transformer in the spec. As I had the
error I mentioned
previously in the body, I changed the formal part with:

   type Transformer is abstract tagged limited private;
   with function Parent_To_Self (This : access Transformer'Class) return
Transformation is <>;
   with function Self_To_Parent (This : access Transformer'Class) return
Transformation is <>;

But then , when I declared the derived type Identity_Transformer I had other
errors with overriding
of operations of Transformer.

So, in fact I happen to ask myself what was the difference between:
   type Root is abstract tagged private;
   with procedure P1 (This : access Root);

and:
   type Root is abstract tagged private;
   with procedure P1 (This : access Root'Class);

The first solution seems to allow derivation (Identity_Transformer) and to
handle dispatching, but
I don't know how to use the operations in the body, whilst the second
solution reverses the problem.

I know that if the Transformer type was defined in the spec of the generic
there would not be any
problem. But I don't want to do it for the following reason:
The actual Transformer type may derive or not from a base type. And I don't
want to write two
versions of the package, one with a base type, and the other without any
base type. This is why
I would like to define a formal generic "interface" (abstract class
+ operations) that can be
"implemented" or derived in the generic (e.g., Identity_Transformer) and
that can be used in the body!

As I have not found any clear (for me) explanation in the RM about formal
primitive operations, I
tried simple examples (I know, examples are not proof!) like:
------------------------------------------------------
generic
   type Root is abstract tagged private;
   with procedure P1 (This : access Root);
package Generic_Deriveds is
   type Derived is new Root with null record;
   procedure P1 (This : access Derived);
end Generic_Deriveds;

with Ada.Text_IO;
package body Generic_Deriveds is
   procedure P1 (This : access Derived) is
   begin
      Ada.Text_IO.Put_Line("Generic_Deriveds.Derived.P1");
   end P1;
end Generic_Deriveds;

package Roots is
   type Root is tagged null record;
   procedure P1 (This: access Root);
end Roots;

with Ada.Text_IO;
package body Roots is
   procedure P1 (This: access Root) is
   begin
      Ada.Text_IO.Put_Line("Roots.Root.P1");
   end P1;
end Roots;

with Roots;
with Generic_Deriveds;
package Deriveds is new Generic_Deriveds(Roots.Root, Roots.P1);

with Roots; use Roots;
with Deriveds; use Deriveds;
procedure Main is
   R : aliased Root;
   D : aliased Derived;
   procedure Check (This : access Root'Class) is
   begin
      P1(This);
   end Check;
begin
   Check(R'Access);
   Check(D'Access);
end Main;
-------------------------------------------------------

Using gnat 3.13a, this compiles and works as I expect (at least I believe it
!), it prints:
Roots.Root.P1
Generic_Deriveds.Derived.P1

And, if I suppress the definition of P1 in Generic_Deriveds, the output is:
Roots.Root.P1
Roots.Root.P1

So this example makes me think that in the declaration:
generic
   type Root is abstract tagged private;
   with procedure P1 (This : access Root);
P1 is a (or may be) interpreted by the compiler as a primitive operation.

The only problem I have is the one illustrated in the first post: I can not
use dispatching in the body
(or I don't know how to do it)

I am afraid to be  bit confusing, but I would really like to understand this
issue.

I whish someone could clarify all this for me!

Thanks !

Damien.





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

* Re: generic formal primitive [dispatching] operation
  2000-09-18  0:00 ` Robert A Duff
@ 2000-09-19  0:00   ` Damien Carbonne
  2000-09-19  0:00     ` Robert A Duff
  0 siblings, 1 reply; 5+ messages in thread
From: Damien Carbonne @ 2000-09-19  0:00 UTC (permalink / raw)


Robert A Duff a �crit :

> Damien Carbonne <damien.carbonne@free.fr> writes:
>
> > I would like to create a generic package that has, as formal parameters,
> > a tagged type and some primitive dispatching operations on that type.
>
> Try using a generic formal derived type.  Declare the root type outside
> the generic, with the primitive you want, and then declare a generic
> formal type derived from that.
>

As I explained in my answer to Thomas Quinot, I would like to avoid this
solution, because it is a bit more rigid than what
I expect. But if what I expect is impossible, I will come back to it.

>
> > 1) How is it possible to define a formal primitive operation on a tagged
> > type that is:
> >    a) non dispatching (Root'Class ??)
>
> Primitive = dispatching (for tagged types).  Class-wide types are not
> primitive.
>
> >    b) dispatching
>
> See above.
>
> > 2) In the case of class-wide operations, is there any difference between
> > primitive and non primitive
> >    operations ? (I would say no ?)
>
> A class-wide operation is *not* primitive.
>
> - Bob

Sorry, I thought "primitivity" was only related to declarative region
+ freezing rules.
But it is in fact more restricted.

Is the following example correctly labelled ?
package P is
   type T is tagged null record;
   procedure Primitive(Obj : T);
   procedure Class_Wide(Obj : T'Class);
end P;

with P; use P;
package O is
   procedure What_Is_Its_Category(Obj : T);
   procedure Again_Class_Wide(Obj ; T'Class);
end O;


Can we consider that in the following declarations:
generic
   type Root is tagged private;
   with procedure P1(This : access Root);
   with procedure P2(This : access Root'Class);


1) P1 is primitive (that is dispatching). Root can be derived and P1
redefined. (It seems to be the case in
   the example I put in my answer to T.Quinot)
2) P2 is class-wide.

If this is true, my problem is, how is it possible to make the initial
example work, keeping the same spec (just changing the body).

Thanks for clarifications.

Damien.






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

* Re: generic formal primitive [dispatching] operation
  2000-09-19  0:00   ` Damien Carbonne
@ 2000-09-19  0:00     ` Robert A Duff
  0 siblings, 0 replies; 5+ messages in thread
From: Robert A Duff @ 2000-09-19  0:00 UTC (permalink / raw)


Damien Carbonne <damien.carbonne@free.fr> writes:

> Sorry, I thought "primitivity" was only related to declarative region
> + freezing rules.
> But it is in fact more restricted.
> 
> Is the following example correctly labelled ?
> package P is
>    type T is tagged null record;
>    procedure Primitive(Obj : T);

Yes, that's primitive of T.

>    procedure Class_Wide(Obj : T'Class);

Yes, that's class-wide.

> end P;
> 
> with P; use P;
> package O is
>    procedure What_Is_Its_Category(Obj : T);

That one is not primitive, because it isn't declared in the same package
spec as T.

>    procedure Again_Class_Wide(Obj ; T'Class);

Yes, that's class-wide -- class-wide operations can be declared
anywhere.

> end O;
> 
> 
> Can we consider that in the following declarations:
> generic
>    type Root is tagged private;
>    with procedure P1(This : access Root);
>    with procedure P2(This : access Root'Class);
> 
> 
> 1) P1 is primitive (that is dispatching). Root can be derived and P1
> redefined. (It seems to be the case in
>    the example I put in my answer to T.Quinot)

No, P1 is not primitive (not dispatching) because it is not declared in
the same package spec as Root.  In fact, Root is not declared in a
package spec, so the only primitive ops of Root are "=" and "/=".

You can get more by inheriting them, as I suggested in a previous
message.

> 2) P2 is class-wide.

Yes.

> If this is true, my problem is, how is it possible to make the initial
> example work, keeping the same spec (just changing the body).

I don't think you can, but maybe I misunderstand what you're trying to
do.

- Bob




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

end of thread, other threads:[~2000-09-19  0:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <39C5321E.805A73D1@free.fr>
2000-09-18  0:00 ` generic formal primitive [dispatching] operation Thomas Quinot
2000-09-19  0:00   ` Damien Carbonne
2000-09-18  0:00 ` Robert A Duff
2000-09-19  0:00   ` Damien Carbonne
2000-09-19  0:00     ` 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