hasan@emx.utexas.edu (David A. Hasan) (03/09/91)
I have a question that deals with using generic subprograms inside packages as a means of factoring out common implementation details of the subprograms exported by the package. Consider a package that exports similar subprograms to its clients: PACKAGE p IS TYPE someType IS ...; FUNCTION f1(arg1,arg2 : IN someType) RETURN someType; FUNCTION f2(arg1,arg2 : IN someType) RETURN someType; END p; and suppose further that the implementations <f1> and <f2> are the same except for one subprogram call. (For example, elementwise addition and subtraction of vectors.) It occurs to me that it might be wise to implement these as instances of one generic function (<g_f>, say) which takes the crucial differing subprogram as a generic parameter. To do this, I could: 1) put the GENERIC DECLARATION and BODY of <g_f> in the body of <p>. In this case, the implementations of <f1> & <f2> would instantiate <g_f>. But of course, this is hogwash: generic instantiations are *declarations* and cannot be used to define the implementation. So, as an alternative... 2) put the GENERIC DECLARATION in the package spec and put the BODY in the body of package <p>. <f1> & <f2> could then be declared as instances of <g_f>. This has the pleasant side effect of exporting to my clients a generic function which they might find useful. This works fine until runtime: when package <p> is elaborated, the instantiations for <f1> and <f2> raise PROGRAM_ERROR, since the package body (and therefore the body of <g_f>) has not yet been elaborated. 3) Implement <f1> and <f2> as "skin" routines which simply call two internal (to the body of <p>) instances of <g_f>. At this point, the simplicity of it all has been lost. One additional solution might be to factor <g_f> outside of the package altogether. However, <f1> and <f2> are fundamentally part of the abstraction provided by package <p> and cannot be implemented independently. Is there some way that I have missed to use generics to factor out common elements of implementations? -- : David A. Hasan : WRW 402 Univ. of Texas at Austin, Austin TX 78712 : internet: hasan@emx.cc.utexas.edu
hasan@ut-emx.uucp (David A. Hasan) (03/12/91)
In article <45358@ut-emx.uucp> I wrote: >PACKAGE p IS > TYPE someType IS ...; > FUNCTION f1(arg1,arg2 : IN someType) RETURN someType; > FUNCTION f2(arg1,arg2 : IN someType) RETURN someType; >END p; [ where <f1> & <f2> differ only in one subprogram call ] >It occurs to me that it might be wise to implement these >as instances of one generic function (<g_f>, say) which takes the >crucial differing subprogram as a generic parameter. >To do this, I could: > 1) put the GENERIC DECLARATION and BODY of <g_f> in the body of <p>. > In this case, the implementations of <f1> & <f2> would > instantiate <g_f>. > But of course, this is hogwash: generic instantiations > are *declarations* and cannot be used to define the > implementation. So, as an alternative... Or *is* it hogwash? This technique is used by Habermann & Perry in their book "Ada for Experienced Programmers". In fact, the LRM seems to indicate that a generic instantiation can be used as the implementation of a subprogram. (I reached this conclusion by threading my way through the BNF -- a technique I often use when I can't find an explicit discussion of my problems.) The DEC compiler objects to the presence of generic instantiations such as FUNCTION f1 is NEW g_f( ... ); on the basis that it constitutes a redclaration of <f1> as it appears in the package spec. Anyone know whether this is legal or not? -- | David A. Hasan | hasan@emx.utexas.edu
loftus@wpllabs.UUCP (William Loftus) (03/14/91)
In article <45441@ut-emx.uucp> hasan@ut-emx.uucp (David A. Hasan) writes: >In article <45358@ut-emx.uucp> I wrote: > >>PACKAGE p IS >> TYPE someType IS ...; >> FUNCTION f1(arg1,arg2 : IN someType) RETURN someType; >> FUNCTION f2(arg1,arg2 : IN someType) RETURN someType; >>END p; > >[ where <f1> & <f2> differ only in one subprogram call ] > >>It occurs to me that it might be wise to implement these >>as instances of one generic function (<g_f>, say) which takes the >>crucial differing subprogram as a generic parameter. >>To do this, I could: > >> 1) put the GENERIC DECLARATION and BODY of <g_f> in the body of <p>. >> In this case, the implementations of <f1> & <f2> would >> instantiate <g_f>. > >> But of course, this is hogwash: generic instantiations >> are *declarations* and cannot be used to define the >> implementation. So, as an alternative... > >Or *is* it hogwash? This technique is used by Habermann & Perry >in their book "Ada for Experienced Programmers". In fact, the >LRM seems to indicate that a generic instantiation can be used >as the implementation of a subprogram. (I reached this >conclusion by threading my way through the BNF -- a technique >I often use when I can't find an explicit discussion of my >problems.) > >The DEC compiler objects to the presence of generic >instantiations such as > > FUNCTION f1 is NEW g_f( ... ); > >on the basis that it constitutes a redclaration of <f1> as it >appears in the package spec. > >Anyone know whether this is legal or not? It is not legal. A generic instantiation introduces both a spec and body (see 12.2(1) and 12.2(2)). A generic instantiation of a procedure in a package body introduces a spec and body for that routine into the package body. If there is a specification of a homograph in the package specification then there is a redeclaring of the specification of the subprogram in the package body, and therefore is illegal. However, this has been submitted by ALWG as a consideration for Ada 9x. Also notice that you cannot use a renames solely as an implemenation, either. -- William Loftus (215) 668 3661 WPL Laboratories, Inc. UUCP: loftus@wpllabs.UUCP P.O. Box 111 ARPA: loftus!wpllabs@prc.unisys.com 216 Wynne Lane Penn Valley, PA 19072 Ada and Unix Software Consultants
hasan@ut-emx.uucp (David A. Hasan) (03/16/91)
In response to a question I asked about using a generic subprogram in the body of a package to implement the bodies of various subprograms exported by that package, loftus@wpllabs.UUCP (William Loftus) writes: >A generic instantiation introduces both a spec and body ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (I see...) >(see 12.2(1) and 12.2(2)). A generic instantiation of a procedure in a >package body introduces a spec and body for that routine into the package >body. If there is a specification of a homograph in the package >specification then there is a redeclaring of the specification of the >subprogram in the package body, and therefore is illegal. However, this >has been submitted by ALWG as a consideration for Ada 9x. > Thank you. The answers my question exactly. I must admit, however, that I still can't see how those two paragraphs of the LRM tell me this. Do you perhaps mean 12(1) and 12(2)? When it says "An instance of a generic subprogram is a subprogram", is it really telling me that a spec and body are generated? My confusion was doubled by the fact that the Meridian compiler which I also use actually compiled what DEC's wouldn't (although I did get a runtime PROGRAM_ERROR). >Also notice that you cannot use a renames solely as an implemenation, >either. Yes, I've tried that in the past and had to mend my ways, also. Is there a 9X consideration of that? Anyway, thanks for the help! -- | David A. Hasan | hasan@emx.utexas.edu