comp.lang.ada
 help / color / mirror / Atom feed
* Extending A Generic Signature Package
@ 1997-03-17  0:00 david scott gibson
  1997-03-18  0:00 ` Tucker Taft
                   ` (3 more replies)
  0 siblings, 4 replies; 13+ messages in thread
From: david scott gibson @ 1997-03-17  0:00 UTC (permalink / raw)



Hi.  Is any way in Ada to extend a generic signature package?  For
example, if I had the signature package Base_Interface:

generic

    type T is limited private;

    with procedure Op1(x: in out T);

package Base_Interface is end;

I would like to extend it to get a new interface with Op1 inherited.
The following code is illegal, but gives an idea of what I'd like to
do.

with Base_Interface;

generic

    type T is new Base_Interface.T;  -- ILLEGAL!!

    with procedure Op2(x: in out T);

package Extended_Interface is end;

I'd be particularly interested if there were some way of doing this
without using tagged types.  For the language lawyers, what would be
the technical barriers to allowing an extension of this sort (not
including there are other ways in Ada to achieve a similar result :-)?

Dave
dgibson@cis.ohio-state.edu






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

* Re: Extending A Generic Signature Package
  1997-03-17  0:00 Extending A Generic Signature Package david scott gibson
@ 1997-03-18  0:00 ` Tucker Taft
  1997-03-18  0:00   ` Alexander V. Konstantinou
  1997-03-21  0:00 ` Jon S Anthony
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 13+ messages in thread
From: Tucker Taft @ 1997-03-18  0:00 UTC (permalink / raw)



david scott gibson (dgibson@thalamus.cis.ohio-state.edu) wrote:

: Hi.  Is any way in Ada to extend a generic signature package?  For
: example, if I had the signature package Base_Interface:

: generic

:     type T is limited private;

:     with procedure Op1(x: in out T);

: package Base_Interface is end;

: I would like to extend it to get a new interface with Op1 inherited.
: The following code is illegal, but gives an idea of what I'd like to
: do.

: with Base_Interface;

: generic

:     type T is new Base_Interface.T;  -- ILLEGAL!!

:     with procedure Op2(x: in out T);

: package Extended_Interface is end;

: I'd be particularly interested if there were some way of doing this
: without using tagged types.  For the language lawyers, what would be
: the technical barriers to allowing an extension of this sort (not
: including there are other ways in Ada to achieve a similar result :-)?

Well, I'm not exactly sure what is your goal, but the following
might satisfy you:

    with Base_Interface;
    generic
        with package Base is new Base_Interface(<>);
        with procedure Op2(x : in out Base.T);
    package Extended_Interface is end;

Given any instantiation of Base_Interface and an appropriate
"Op2", you can create an instantiation of Extended_Interface as follows:

    with Extended_Interface;
    with My_Base;
    with ...appropriate other stuff...
    package Extended is new Extended_Interface(My_Base, My_Op2);

: Dave
: dgibson@cis.ohio-state.edu

-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Burlington, MA  USA




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

* Re: Extending A Generic Signature Package
  1997-03-18  0:00 ` Tucker Taft
@ 1997-03-18  0:00   ` Alexander V. Konstantinou
  1997-03-21  0:00     ` Geert Bosch
  0 siblings, 1 reply; 13+ messages in thread
From: Alexander V. Konstantinou @ 1997-03-18  0:00 UTC (permalink / raw)



Tucker Taft (stt@houdini.camb.inmet.com) wrote:
: david scott gibson (dgibson@thalamus.cis.ohio-state.edu) wrote:

: : Hi.  Is any way in Ada to extend a generic signature package?  For
: : example, if I had the signature package Base_Interface:

[snip]

: Well, I'm not exactly sure what is your goal, but the following
: might satisfy you:

:     with Base_Interface;
:     generic
:         with package Base is new Base_Interface(<>);
:         with procedure Op2(x : in out Base.T);
:     package Extended_Interface is end;

: Given any instantiation of Base_Interface and an appropriate
: "Op2", you can create an instantiation of Extended_Interface as follows:

:     with Extended_Interface;
:     with My_Base;
:     with ...appropriate other stuff...
:     package Extended is new Extended_Interface(My_Base, My_Op2);

Unfortunately, with the above code one is either forced to
reexport the Base_Interface operations in Extended_Interface
or the user has to "use" all the new generic rackage
instances (i.e. use My_Extended; use My_Extended.Base;).
If you don't like "use" clauses, then you need to remember
where in the hierarchy an operation is defined.

OO people will tell you to use inheritance, but there is
really no reason to pay for the overhead when your abstraction
can be served by a compile-time check.

Anyone know how to do this without restricting writability?
I have ended up many times repeating the operations in
the "Extended" to make use easier.


-- 
Alexander V. Konstantinou              http://www.cs.columbia.edu/~akonstan/
akonstan@cs.columbia.edu               akonstan@acm.org




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

* Re: Extending A Generic Signature Package
  1997-03-17  0:00 Extending A Generic Signature Package david scott gibson
  1997-03-18  0:00 ` Tucker Taft
@ 1997-03-21  0:00 ` Jon S Anthony
  1997-03-21  0:00   ` david scott gibson
  1997-03-22  0:00 ` Jon S Anthony
  1997-03-25  0:00 ` Jon S Anthony
  3 siblings, 1 reply; 13+ messages in thread
From: Jon S Anthony @ 1997-03-21  0:00 UTC (permalink / raw)



In article <5gtvbv$1nj@pandora.cs.utwente.nl> boschg@cs.utwente.nl (Geert Bosch) writes:

> Dispatching occurs when you use (pointers to) class-wide types like
> in the following case:
> 
>    declare
>        type Object_Ptr is access all Base'Class;
>       X : Object_Ptr := new Base;
>    begin
>       Op1 (X.all);
>    end;

Just to be clear, "pointers" are only indirectly relevant to
dispatching.  The key is passing a class wide type argument(s) to a
controlling operand(s) of a primitive operation.  For example, there
is no need of a pointer in your above example:

    declare
       X : Base'Class := Get_Object;
    begin
       Op1(X);
    end;

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





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

* Re: Extending A Generic Signature Package
  1997-03-21  0:00 ` Jon S Anthony
@ 1997-03-21  0:00   ` david scott gibson
  1997-03-22  0:00     ` Robert A Duff
  0 siblings, 1 reply; 13+ messages in thread
From: david scott gibson @ 1997-03-21  0:00 UTC (permalink / raw)



In article <JSA.97Mar21135016@alexandria>,
Jon S Anthony <jsa@alexandria> wrote:

>Just to be clear, "pointers" are only indirectly relevant to
>dispatching.  The key is passing a class wide type argument(s) to a
>controlling operand(s) of a primitive operation.  For example, there
>is no need of a pointer in your above example:
>
>    declare
>       X : Base'Class := Get_Object;
>    begin
>       Op1(X);
>    end;

So in this case it's clear to us and the compiler what specific type
derived from Base Get_Object returns.  It may or may not be an access
type.  If an access type, Op1 could have an access parameter formal
and still dispatch.  However, Get_Object must return a tagged type and
thus the value returned must be returned by reference in either case,
right?  So whether explicit or not X, the value of X must be a pointer
to some object.  Is that right?  If Get_Object doesn't return an acces
type and we don't use Unchecked_Access or aliased variables anywhere
in the program, does Ada guarantee that the object to which X points
cannot be aliased?

Dave
--
dgibson@cis.ohio-state.edu





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

* Re: Extending A Generic Signature Package
  1997-03-21  0:00     ` Geert Bosch
@ 1997-03-21  0:00       ` Brian Rogoff
  1997-03-22  0:00         ` Robert A Duff
  0 siblings, 1 reply; 13+ messages in thread
From: Brian Rogoff @ 1997-03-21  0:00 UTC (permalink / raw)



On 21 Mar 1997, Geert Bosch wrote:

> Alexander V. Konstantinou (akonstan@news.cs.columbia.edu) wrote:
> : OO people will tell you to use inheritance, but there is
> : really no reason to pay for the overhead when your abstraction
> : can be served by a compile-time check.
> 
> You shouldn't confuse using tagged types with dynamic dispatching. 
> Suppose you have this situation:

	I don't think he is. What I believe Alexander is suggesting is 
that the generic signature package provides an overhead free method for 
reusing data type specifications in new contexts.

> <details of tagged type approach deleted>
>    
> So whether a call to a primitive operation on a tagged type is dispatching or
> not is determined at the call-site. I don't know why you wouldn't want to use
> tagged types in your situation. The per-object space overhead shouldn't be
> more than one or to pointers in most compilers. 

	What if the objects are small, and there are very many of them?
Example: your signatures are of numeric types which are the elements of 
         matrices in a numerical linear algebra package. One or two
         pointers per object is too much.

	What if you just want to reuse the objects, which aren't tagged, 
and you can't rewrite them? Generic signature packages allow this. 

	I think in answer to Alexander's question, I would reexport the ops 
at each level. I don't know of any approaches that satisfy your
"writability" constraint. 

-- Brian






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

* Re: Extending A Generic Signature Package
  1997-03-22  0:00 ` Jon S Anthony
@ 1997-03-21  0:00   ` david scott gibson
  1997-03-22  0:00     ` Robert A Duff
  0 siblings, 1 reply; 13+ messages in thread
From: david scott gibson @ 1997-03-21  0:00 UTC (permalink / raw)



In article <JSA.97Mar21200655@alexandria>,
Jon S Anthony <jsa@alexandria> wrote:

>> >    declare
>> >       X : Base'Class := Get_Object;
>> >    begin
>> >       Op1(X);
>> >    end;
>> 
>> So in this case it's clear to us and the compiler what specific type
>> derived from Base Get_Object returns.
>
>No, the _specific_ type is unknown until runtime.  But, whatever it
>is, it will be in Base'Class.

Hmmm.  I was thinking of Get_Object as a constructor for a specific
derived type of Base.  Are you're suggesting some non-functional
behavior here for Get_Object to be able to return any one of several
specific derived types?

>Ah.  This is something that many people trip over: an access object
>(or "pointer") is not the same thing as an object that happens to be
>passed by reference.  Also, tagged types are not necessarily return by
>reference types (_limited_ tagged types are: see 6.5(11)).

Okay, I've primarily been using limited tagged types lately and forgot
that this rule only applied to them.  Nevertheless, I assume compilers
may return tagged types, especially big ones, by reference.  I didn't
mean to imply that objects passed by reference should be thought of as
"pointers".  Ada seems to do a good job of making the mechanism
transparent.  

Dave
--
dgibson@cis.ohio-state.edu







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

* Re: Extending A Generic Signature Package
  1997-03-18  0:00   ` Alexander V. Konstantinou
@ 1997-03-21  0:00     ` Geert Bosch
  1997-03-21  0:00       ` Brian Rogoff
  0 siblings, 1 reply; 13+ messages in thread
From: Geert Bosch @ 1997-03-21  0:00 UTC (permalink / raw)



Alexander V. Konstantinou (akonstan@news.cs.columbia.edu) wrote:
: OO people will tell you to use inheritance, but there is
: really no reason to pay for the overhead when your abstraction
: can be served by a compile-time check.

You shouldn't confuse using tagged types with dynamic dispatching. 
Suppose you have this situation:

   type Base is tagged record ... end record;
   procedure Op1 (X : in out Base);
   procedure Op2 (X : in out Base);

   type Extended is new Base with ...;
   procedure Op1 (X : in out Extended);
   procedure Op3 (X : in out Extended);

In this case you can just declare an object of type Extended and use
the operations Op1, Op2 and Op3 without any overhead due to dispatching. 
Dispatching occurs when you use (pointers to) class-wide types like
in the following case:

   declare
       type Object_Ptr is access all Base'Class;
      X : Object_Ptr := new Base;
   begin
      Op1 (X.all);
   end;
   
So whether a call to a primitive operation on a tagged type is dispatching or
not is determined at the call-site. I don't know why you wouldn't want to use
tagged types in your situation. The per-object space overhead shouldn't be
more than one or to pointers in most compilers. 

Regards,
   Geert




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

* Re: Extending A Generic Signature Package
  1997-03-17  0:00 Extending A Generic Signature Package david scott gibson
  1997-03-18  0:00 ` Tucker Taft
  1997-03-21  0:00 ` Jon S Anthony
@ 1997-03-22  0:00 ` Jon S Anthony
  1997-03-21  0:00   ` david scott gibson
  1997-03-25  0:00 ` Jon S Anthony
  3 siblings, 1 reply; 13+ messages in thread
From: Jon S Anthony @ 1997-03-22  0:00 UTC (permalink / raw)



In article <5guuehINN6iq@thalamus.cis.ohio-state.edu> dgibson@thalamus.cis.ohio-state.edu (david scott gibson) writes:

> Jon S Anthony <jsa@alexandria> wrote:
> 
> >Just to be clear, "pointers" are only indirectly relevant to
> >dispatching.  The key is passing a class wide type argument(s) to a
> >controlling operand(s) of a primitive operation.  For example, there
> >is no need of a pointer in your above example:
> >
> >    declare
> >       X : Base'Class := Get_Object;
> >    begin
> >       Op1(X);
> >    end;
> 
> So in this case it's clear to us and the compiler what specific type
> derived from Base Get_Object returns.

No, the _specific_ type is unknown until runtime.  But, whatever it
is, it will be in Base'Class.

>  It may or may not be an access type.

In this particular case (as written) it cannot be an access type as no
access type is legal as a specific type of any class-wide type (only
tagged types are so legal).


> If an access type, Op1 could have an access parameter formal
> and still dispatch.

Yes, if there were an access type to Base'Class being returned (which
as it is written can't be), Op1 could have a controlling parameter of
an annonymous access to some specific type in Base'Class and it would
still dispatch as you would expect.

>  However, Get_Object must return a tagged type and thus the value
> returned must be returned by reference in either case, right?

Ah.  This is something that many people trip over: an access object
(or "pointer") is not the same thing as an object that happens to be
passed by reference.  Also, tagged types are not necessarily return by
reference types (_limited_ tagged types are: see 6.5(11)).


> So whether explicit or not X, the value of X must be a pointer
> to some object.  Is that right?

No, that's not correct.  If X is not explicitly an access object, its
value is not a "pointer" to some object.


> If Get_Object doesn't return an acces type and we don't use
> Unchecked_Access or aliased variables anywhere in the program, does
> Ada guarantee that the object to which X points cannot be aliased?

Depends on what you mean by "aliased".  The most typical
interpretation would be that it means referenced by more than one
object.  For this case, Ada alone does not offer any guarantee.


/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





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

* Re: Extending A Generic Signature Package
  1997-03-21  0:00   ` david scott gibson
@ 1997-03-22  0:00     ` Robert A Duff
  0 siblings, 0 replies; 13+ messages in thread
From: Robert A Duff @ 1997-03-22  0:00 UTC (permalink / raw)



In article <5gvgg0INNj32@snoopy.cis.ohio-state.edu>,
david scott gibson <dgibson@snoopy.cis.ohio-state.edu> wrote:
>Okay, I've primarily been using limited tagged types lately and forgot
>that this rule only applied to them.  Nevertheless, I assume compilers
>may return tagged types, especially big ones, by reference.

No, not unless the compiler can prove it makes no difference.  E.g.:

    Global: T'Class := ...;

    function F return T'Class is
    begin
        return Global;
    end F;
    
    X: T'Class := F;
    ...
    Global.Component := 3;

X and Global are not aliased.  A copy must be made at the return
statement.  The assignment to a component of Global does not modify X.
(The fact that the generated code might assume that F returns the
address of the result in register R0 is irrelevant -- if that's what's
going on, R0 will point to a *copy* of Global.)  If T were limited, then
F would return its result by reference, but then the above would be
illegal, due to the ":= F".

>...  I didn't
>mean to imply that objects passed by reference should be thought of as
>"pointers".  Ada seems to do a good job of making the mechanism
>transparent.  

Parameter passing mechanism is not transparent in Ada -- you can tell
the difference between by-ref and by-copy, and Ada allows either one
(compiler's choice) in some cases.  (I happen to think that's a flaw in
the language.  We've discussed it here before.)  For function return, on
the other hand, the language always requires by-ref or by-copy -- the
choice is not up to the compiler.

- Bob




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

* Re: Extending A Generic Signature Package
  1997-03-21  0:00       ` Brian Rogoff
@ 1997-03-22  0:00         ` Robert A Duff
  0 siblings, 0 replies; 13+ messages in thread
From: Robert A Duff @ 1997-03-22  0:00 UTC (permalink / raw)



In article <Pine.SGI.3.95.970321164136.22672B-100000@shellx.best.com>,
Brian Rogoff  <bpr@best.com> wrote:
>	What if the objects are small, and there are very many of them?
>Example: your signatures are of numeric types which are the elements of 
>         matrices in a numerical linear algebra package. One or two
>         pointers per object is too much.

It's really just *one* pointer -- I don't of any implementation that
uses two, and I don't know any reason why it would want to (at least,
not as the default implementation of tagged types).  I agree that even
just one pointer is too much in the case above.

It would be nice if it were possible to implement tagged types without
storing a tag in every object.  It is *almost* possible to do that.  The
problem is that all tagged parameters are aliased, so the tag needs to
be stored.  The only way around that I can see would be to do some
global (link time) analysis of the program.

- Bob




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

* Re: Extending A Generic Signature Package
  1997-03-21  0:00   ` david scott gibson
@ 1997-03-22  0:00     ` Robert A Duff
  0 siblings, 0 replies; 13+ messages in thread
From: Robert A Duff @ 1997-03-22  0:00 UTC (permalink / raw)



In article <5guuehINN6iq@thalamus.cis.ohio-state.edu>,
david scott gibson <dgibson@thalamus.cis.ohio-state.edu> wrote:
>So in this case it's clear to us and the compiler what specific type
>derived from Base Get_Object returns.  It may or may not be an access
>type.  If an access type, Op1 could have an access parameter formal
>and still dispatch.  However, Get_Object must return a tagged type and
>thus the value returned must be returned by reference in either case,
>right?

No, tagged types are returned by copy, unless the type is limited.

>...  So whether explicit or not X, the value of X must be a pointer
>to some object.  Is that right?  If Get_Object doesn't return an acces
>type and we don't use Unchecked_Access or aliased variables anywhere
>in the program, does Ada guarantee that the object to which X points
>cannot be aliased?

Not sure exactly what you're getting at, but Ada allows and/or requires
pass-by-reference in some cases, and those constitute aliases in the
normal sense of the word.

- Bob




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

* Re: Extending A Generic Signature Package
  1997-03-17  0:00 Extending A Generic Signature Package david scott gibson
                   ` (2 preceding siblings ...)
  1997-03-22  0:00 ` Jon S Anthony
@ 1997-03-25  0:00 ` Jon S Anthony
  3 siblings, 0 replies; 13+ messages in thread
From: Jon S Anthony @ 1997-03-25  0:00 UTC (permalink / raw)



In article <5gvgg0INNj32@snoopy.cis.ohio-state.edu> dgibson@snoopy.cis.ohio-state.edu (david scott gibson) writes:

> In article <JSA.97Mar21200655@alexandria>,
> Jon S Anthony <jsa@alexandria> wrote:
> 
> >> >    declare
> >> >       X : Base'Class := Get_Object;
> >> >    begin
> >> >       Op1(X);
> >> >    end;
> >> 
> >> So in this case it's clear to us and the compiler what specific type
> >> derived from Base Get_Object returns.
> >
> >No, the _specific_ type is unknown until runtime.  But, whatever it
> >is, it will be in Base'Class.
> 
> Hmmm.  I was thinking of Get_Object as a constructor for a specific
> derived type of Base.  Are you're suggesting some non-functional
> behavior here for Get_Object to be able to return any one of several
> specific derived types?

I don't know what you mean by "non-functional behavior".  Certainly,
as you suggest, Get_Object could be a constructor for a specific type
in Base'Class, but I was thinking of a different situation.  Suppose
it returns Base'Class and computes the object of the appropriate
specific type on the fly.  Or perhaps, it dispatches (in which case it
needs a parameter of some sort) to the appropriate specific Get_Object
or some combination of these.  Anyway, you get the idea.


> that this rule only applied to them.  Nevertheless, I assume compilers
> may return tagged types, especially big ones, by reference.  I didn't
> mean to imply that objects passed by reference should be thought of as
> "pointers".  Ada seems to do a good job of making the mechanism
> transparent.  

Bob answered this one.

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





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

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

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-03-17  0:00 Extending A Generic Signature Package david scott gibson
1997-03-18  0:00 ` Tucker Taft
1997-03-18  0:00   ` Alexander V. Konstantinou
1997-03-21  0:00     ` Geert Bosch
1997-03-21  0:00       ` Brian Rogoff
1997-03-22  0:00         ` Robert A Duff
1997-03-21  0:00 ` Jon S Anthony
1997-03-21  0:00   ` david scott gibson
1997-03-22  0:00     ` Robert A Duff
1997-03-22  0:00 ` Jon S Anthony
1997-03-21  0:00   ` david scott gibson
1997-03-22  0:00     ` Robert A Duff
1997-03-25  0:00 ` Jon S Anthony

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