comp.lang.ada
 help / color / mirror / Atom feed
* Dispatching In Generics
@ 1997-06-05  0:00 Kevin Ingalls
  1997-06-07  0:00 ` Tom Moran
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Kevin Ingalls @ 1997-06-05  0:00 UTC (permalink / raw)



First, I can't find the Ada FAQ, so perhaps the answer to my question is
there. If you know where it is I would appreciate the address.

Second, here is my coding question: How do I code a generic so that it
can take the base type of a hierarchy and perform dispatching on objects
of that type?

Specifically, given:
	package A with an abstract tagged type X
	a primitive operation "operation" on type X
	child package A.B with a derived type Y
	a primitive operation "operation" on type Y
How do I write a generic that can handle objects of X'class, including
dispatching operations correctly?

Here is the skeleton of a first try:
	
----------------------------
with ada.finalization;
package A is
	type X is abstract tagged private;
	procedure operation (anX : X);
private
	type X is abstract new ada.finalization.controlled with...
end A;

package A.B is
	type Y is new X with private;
	procedure operation (aY : Y);
private
	type Y is new X with record...
end A.B;

generic
	type T is abstract tagged private;
	with procedure op (aT : T);
package gPackage is
	procedure P;
end gPackage;

package body gPackage is
	procedure P is
	begin
		op (object_of_type_T); -- here is the syntax error
	end P;
end gPackage;

with A, gPackage;
package instance is new gPackage(A.X, A.operation);
----------------------------

The syntax error occurs while compiling the generic on the marked line.
I understand that I have no subprograms with class-wide parameters, and
so "op" cannot do dispatching (which is what the error message tells
me). The question is, what is the correct way to accomplish this?

As a kludge, I added a class-wide operation to package A for type X:
----
	procedure operation_class_wide (aClassWideX : X'class);
----
	procedure operation_class_wide (aClassWideX : X'class) is
	begin
		operation(aClassWideX);
	end operation_class_wide;

And changed the instantiation to:

package instance is new gPackage (A.X, A.operation_class_wide);

But this is hardly a clean solution. So, the question is how can I write
a generic package to handle a class hierarchy, including
dispatching-like behavior, cleanly?

-- 

Kevin Ingalls, (206)773-9404, kevin.l.ingalls@boeing.com




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

* Re: Dispatching In Generics
  1997-06-05  0:00 Dispatching In Generics Kevin Ingalls
@ 1997-06-07  0:00 ` Tom Moran
  1997-06-09  0:00 ` Robert A Duff
  1997-06-09  0:00 ` John English
  2 siblings, 0 replies; 6+ messages in thread
From: Tom Moran @ 1997-06-07  0:00 UTC (permalink / raw)



Well, you clearly cannot have an "object_of_type_T" in your code as
written
>  op (object_of_type_T);
 since T (and its intantiation as A.X) are abstract.




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

* Re: Dispatching In Generics
  1997-06-05  0:00 Dispatching In Generics Kevin Ingalls
  1997-06-07  0:00 ` Tom Moran
  1997-06-09  0:00 ` Robert A Duff
@ 1997-06-09  0:00 ` John English
  2 siblings, 0 replies; 6+ messages in thread
From: John English @ 1997-06-09  0:00 UTC (permalink / raw)



Kevin Ingalls (kevin.l.ingalls@boeing.com) wrote:
: First, I can't find the Ada FAQ, so perhaps the answer to my question is
: there. If you know where it is I would appreciate the address.

http://www.adahome.com (where else!)

: Second, here is my coding question: How do I code a generic so that it
: can take the base type of a hierarchy and perform dispatching on objects
: of that type?

with Xpackage;
generic
   type T is abstract new Xpackage.X with private;
   ...
package gPackage is ...

So in gPackage, you can assume that T is descended from X and use X's
primitives.

Hope this helps.

---------------------------------------------------------------
 John English              | mailto:je@brighton.ac.uk
 Senior Lecturer           | http://www.comp.it.bton.ac.uk/je
 Dept. of Computing        | fax: (+44) 1273 642405
 University of Brighton    |
---------------------------------------------------------------




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

* Re: Dispatching In Generics
  1997-06-05  0:00 Dispatching In Generics Kevin Ingalls
  1997-06-07  0:00 ` Tom Moran
@ 1997-06-09  0:00 ` Robert A Duff
  1997-06-09  0:00 ` John English
  2 siblings, 0 replies; 6+ messages in thread
From: Robert A Duff @ 1997-06-09  0:00 UTC (permalink / raw)



In article <3396EB36.3D14@boeing.com>,
Kevin Ingalls  <kevin.l.ingalls@boeing.com> wrote:
>		op (object_of_type_T); -- here is the syntax error

It would be easier to answer your question if you posted the exact code
that you compiled, and the exact error message the compiler gave.  And
maybe even which compiler (and which version) it was.

Anyway, I think what you're looking for is generic formal derived
types.  They drag in their primitive ops with them, and (if tagged) the
generic can dispatch to them.

- Bob




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

* Dispatching in Generics
@ 1997-09-11  0:00 Kevin Ingalls
  1997-09-12  0:00 ` Robert A Duff
  0 siblings, 1 reply; 6+ messages in thread
From: Kevin Ingalls @ 1997-09-11  0:00 UTC (permalink / raw)



Hello,
I am trying to write a generic queue package in Ada95 will allow me to
queue up objects that are of a type hierarchy. For example, I might have
a parent tagged type A that has a derived type B and C. I want to be
able to put an object of either type A, B, or C onto a queue. So, I use
tagged types, hierarchical packages, generics, and classwide access
types. Almost everything works. What doesn't work is dispatching with
generics.
Let's say that in this A,B,C hierarchy I have a primative operation
"put". I want to be able to walk through my queue and "put" each
element, and, of course, I want the correct "put" to be called (i.e., I
want dispatching). How is this done? Here is a small example of the
problem (the error message is from ObjectAda 7.1)

------------------Code Fragment-----------------------
generic
    type T is tagged private;
    with procedure put (T1 : T);
package G is
    procedure cant_dispatch(TC : T'class);
end G;

package body G is
    procedure cant_dispatch(TC : T'class) is
    begin
        put (TC);	-- the error occurs here
    end cant_dispatch;
end G;
-----------------Error Message-------------------------    
cant_dispatch.ada: Error: line 11 col 14 LRM:3.9.2(9), If the expected
type of a name or expression is a tagged type, then it shall not be
dynamically tagged unless it is a controlling operand in a call on a
dispatching operation, Continuing
-----------------End of Error Message------------------

I understand why this doesn't work, but I don't know how to get around
it. The only work-around that I have found so far is to add a classwide
operation to the A,B,C hierarchy. The classwide operation simply does a
dispatching call to the primative operation. I then change the generic
formal parameter to take the classwide operation, instead of the
primitive operation. However, this violates the spirit of generics in
that it requires the generic actual type to know that a classwide
operation is needed for the generic to work correctly. That is, my goal
was to write a generic queue that could take objects of *any* hierarchy,
not only those that have a classwide operation bolted on.

My second question is why is this so difficult to do? Maybe when the
answer is pointed out to me, I'll take that back :-), but this seems
like a fairly straight-forward use to the language. I'm hardly a
proponant of C++, but I wrote the C++ version of this problem in about
1/2 an hour. What important software engineering concept is being
violated in what I am trying to do?

Thanks for any insight you might have.

-- 
Kevin Ingalls
kevin.l.ingalls@boeing.com
(253)773-9404




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

* Re: Dispatching in Generics
  1997-09-11  0:00 Dispatching in Generics Kevin Ingalls
@ 1997-09-12  0:00 ` Robert A Duff
  0 siblings, 0 replies; 6+ messages in thread
From: Robert A Duff @ 1997-09-12  0:00 UTC (permalink / raw)



In article <34183CD3.7F4@boeing.com>,
Kevin Ingalls  <kevin.l.ingalls@boeing.com> wrote:
>generic
>    type T is tagged private;
>    with procedure put (T1 : T);
>package G is
>    procedure cant_dispatch(TC : T'class);
>end G;
>
>package body G is
>    procedure cant_dispatch(TC : T'class) is
>    begin
>        put (TC);	-- the error occurs here
>    end cant_dispatch;
>end G;

Would the following solve your problem?  Declare the formal type with
(<>), and pass in Whatever_Type'Class during instantiation.  Then, all
calls within the generic will necessarily be dispatching.

- Bob




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

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

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-09-11  0:00 Dispatching in Generics Kevin Ingalls
1997-09-12  0:00 ` Robert A Duff
  -- strict thread matches above, loose matches on Subject: below --
1997-06-05  0:00 Dispatching In Generics Kevin Ingalls
1997-06-07  0:00 ` Tom Moran
1997-06-09  0:00 ` Robert A Duff
1997-06-09  0:00 ` John English

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