Talk About Network



Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > Ada > Generics with c...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 1 of 11 Topic 5629 of 5696
Post > Topic >>

Generics with concrete and class-wide types

by Maciej Sobczak <see.my.homepage@[EMAIL PROTECTED] > Mar 31, 2008 at 01:22 PM

Consider a generic subprogram that makes sense for arguments of both
class-wide type and a concrete type.

As a motivating example, there might be a hierarchy of iterator types
rooted in some imaginary Iterator type that is itself defined in the
generic package with the element type as its own formal parameter.
There are concrete iterator types that are derived from this root
Iterator type (exactly: from some instantiation thereof).

There might be also a generic subprogram that operates on the iterator
given as its parameter. This subprogram takes two formal generic
parameters: the element type and the iterator type.

Now - on one hand it makes sense to have a hierarchy of iterators and
benefit from loose coupling and other features of OO, but on the other
hand the iterators themselves can be lightweight objects that are used
in tight loops and we can expect them to be fast, therefore we could
benefit from *avoiding* the dynamic dispatch if there is enough
context to do so.

Both make sense, depending on the context at the call site.

To achieve both benefits the user might instantiate the subprogram for
the Iterator'Class type (to be exact: for the 'Class of some
instantiation of Iterator) in the context where only a class-wide type
is available, like within some other polymorphic subprogram; and for
the concrete type, like My_Concrete_Iterator, in the context where the
concrete type is available, with the hope that such an instantiation
can be more easily inlined.

The sketch of types involved is:

generic
  type T is private; -- element type
package Iterators is
  type Iterator is interface;
  function Get (I : Iterator) return T is abstract;
  -- and so on for other operations...
end Iterators;

and at the user side (let's suppose the user works with Integers
only):

package body My_Stuff is
  package Iterators_Integer is new Iterators (T => Integer);
  type My_Concrete_Iterator is new Iterators_Integer.Iterator with ...

  overriding function Get (I : My_Concrete_Iterator) return Integer;
  -- and so on for other operations...

end My_Stuff;

Now, the generic subprogram that operates on the given iterator,
*without* using dynamic dispatch, can have the following form:

generic
  type Element is private;
  type Iterator_Type (<>) is private;
  with function Get (I : Iterator_Type) return Element is <>;
  -- and so on for all other operations that are needed by this
subprogram
procedure Some_Procedure (I : in Iterator_Type);

This works fine for direct instantiation with My_Concrete_Iterator:

procedure SP is new Some_Procedure
  (T => Integer, Iterator_Type => My_Concrete_Iterator);

The problem is that I failed to instantiate Some_Procedure for
Iterator_Integer.Iterator'Class, which I could then reuse for
My_Concrete_Iterator as well as for My_Other_Concrete_Iterator and so
on:

-- does not compile:
procedure SP is new Some_Procedure
  (T => Integer, Iterator_Type => Iterator_Integer'Class); -- Bang!

Bang, because relevant iterator operations cannot be found - the ones
that are found have *wrong signatures*.

Separate version of Some_Procedure can be written for polymorphic
operations:

generic
  type Element is private;
  with package Its is new Iterators (T => Element);
  -- no need to enumerate any operations, the interface serves its
purpose
procedure Some_Procedure (I : in Its.Iterator'Class);

This works fine when some instantiation of base Iterator type is
given:

procedure SP is new Some_Procedure
  (T => Integer, Its => Iterators_Integer);

and then SP can be used with My_Concrete_Iterator, presumably
dispatching on all calls to iterator in its body.

My expectation is that there should be a way to implement only one
generic procedure that can be instantiated for both concrete types and
for 'Class type.
Otherwise, I would need to provide both versions of Some_Procedure,
which not only looks like unnecessary duplication of code (the
implementations would be even textually identical!), but also seems to
be impossible - for some reason these two versions cannot exist in the
same package. What the heck?

I did not expect two orthogonal language features (generics and OO) to
interact in such a way.
Is there a good solution to this problem?

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com




 11 Posts in Topic:
Generics with concrete and class-wide types
Maciej Sobczak <see.my  2008-03-31 13:22:10 
Re: Generics with concrete and class-wide types
Adam Beneschan <adam@[  2008-03-31 16:38:41 
Re: Generics with concrete and class-wide types
"Randy Brukardt"  2008-04-01 15:10:13 
Re: Generics with concrete and class-wide types
"Randy Brukardt"  2008-03-31 19:23:03 
Re: Generics with concrete and class-wide types
Eric Hughes <eric.eh9@  2008-03-31 20:57:57 
Re: Generics with concrete and class-wide types
christoph.grein@[EMAIL PR  2008-03-31 23:58:59 
Re: Generics with concrete and class-wide types
Georg Bauhaus <rm.tsoh  2008-04-01 09:22:56 
Re: Generics with concrete and class-wide types
"Dmitry A. Kazakov&q  2008-04-01 11:42:18 
Re: Generics with concrete and class-wide types
Maciej Sobczak <see.my  2008-04-01 02:51:19 
Re: Generics with concrete and class-wide types
"Dmitry A. Kazakov&q  2008-04-01 12:53:04 
Re: Generics with concrete and class-wide types
Adam Beneschan <adam@[  2008-04-01 14:17:56 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Tue May 13 7:55:01 CDT 2008.