From: Adam Beneschan <adam@irvine.com>
Subject: Re: Generics with concrete and class-wide types
Date: Mon, 31 Mar 2008 16:38:41 -0700 (PDT)
Date: 2008-03-31T16:38:41-07:00 [thread overview]
Message-ID: <f0879dc0-7498-48f7-8d44-9856316d35ce@s19g2000prg.googlegroups.com> (raw)
In-Reply-To: 279b6f4f-36cf-446f-8b54-fd72b957b22f@i7g2000prf.googlegroups.com
On Mar 31, 1:22 pm, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
> Consider a generic subprogram that makes sense for arguments of both
> class-wide type and a concrete type.
[snip]
> 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*.
[snip]
At first, I thought it might be possible to do this, without
duplicating code, by writing a second generic package specifically for
class-wide types that would instantiate Some_Procedure. Something
like this:
generic
type Element is private;
type Iterator_Root is tagged private;
with function Get (I : in Iterator_Root) return Element is <>;
... other operations
package SP_For_Class is
procedure Some_Procedure_Class (I : in Iterator_Root'Class);
end SP_For_Class;
with Some_Procedure;
package body SP_For_Class is
function Dispatching_Get (I : in Iterator_Root'Class)
return Element is
begin
return Get (I);
end Dispatching_Get;
... similarly for other operations
procedure SP_Inst is new Some_Procedure
(Element, Iterator_Root'Class,
Dispatching_Get, ...other operations);
procedure Some_Procedure_Class (I : in Iterator_Root'Class)
renames SP_Inst;
end SP_For_Class;
Then for a concrete type, the programmer would instantiate
Some_Procedure; for a class-wide type, the programmer would
instantiate SP_For_Class, and then if Inst is the instance,
Inst.Some_Procedure_Class would be the equivalent procedure.
SP_For_Class would be sort of a wrapper, but it wouldn't need to
duplicate any of the logic from Some_Procedure.
The problem I ran into was the line "return Get(I)" fails because Get
is not a primitive operation of Iterator_Root and thus is not seen as
a dispatching operation.
What's missing here is a way to specify a generic formal subprogram
that must be a primitive operation of some tagged type (possibly a
generic formal tagged type), so that in the body of the generic the
formal subprogram will be treated as a dispatching operation; in an
instantiation, of course, the actual subprogram would have to meet the
criterion. It seems like this might be a useful feature in some
cases besides this one (although I can't think of one offhand), but
I can see how it would be difficult to work this into the syntax.
(Especially if the generic formal subprogram has two different
parameter or result tagged types; you'd need a way to tell it which
type the subprogram must be a primitive operation of.)
(P.S. It seems like we had a discussion on Ada-Comment some years ago
about the sort of issue Maciej mentions, at least with regard to the
"=" function. Some programmers were writing code, which GNAT accepted
due a bug, where generics declared
with function "=" (Left, Right : T) is <>;
and then the generic was instantiated with some class-wide type for
T. It
seemed like there was some sympathy for allowing this or providing for
a capability that would make this work, but not enough sympathy for
anyone to actually do anything about it. Bob Duff, does this ring a
bell at all?)
-- Adam
next prev parent reply other threads:[~2008-03-31 23:38 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-03-31 20:22 Generics with concrete and class-wide types Maciej Sobczak
2008-03-31 23:38 ` Adam Beneschan [this message]
2008-04-01 20:10 ` Randy Brukardt
2008-04-01 21:17 ` Adam Beneschan
2008-04-01 0:23 ` Randy Brukardt
2008-04-01 3:57 ` Eric Hughes
2008-04-01 6:58 ` christoph.grein
2008-04-01 7:22 ` Georg Bauhaus
2008-04-01 9:42 ` Dmitry A. Kazakov
2008-04-01 9:51 ` Maciej Sobczak
2008-04-01 10:53 ` Dmitry A. Kazakov
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox