comp.lang.ada
 help / color / mirror / Atom feed
From: Keean Schupke <keean.schupke@googlemail.com>
Subject: Re: Signature Package With Generic Proceedure
Date: Sun, 22 Jul 2012 09:22:55 -0700 (PDT)
Date: 2012-07-22T09:22:55-07:00	[thread overview]
Message-ID: <88734b25-68e5-42b2-89ea-0c0e3fc9fbc5@googlegroups.com> (raw)
In-Reply-To: <a1816272-ef92-4402-bc3a-991bd8522697@googlegroups.com>

On Saturday, 21 July 2012 23:22:36 UTC+1, Adam Beneschan  wrote:
> On Saturday, July 21, 2012 10:22:25 AM UTC-7, Keean Schupke wrote:
> &gt; If I have a package which defines a procedure like:
> &gt; 
> &gt; 
> &gt; generic
> &gt;     with procedure Process(Set : in out Set_Type);
> &gt; procedure Update(Set : in out Set_Type);
> &gt; 
> &gt; 
> &gt; How do a declare a Signature package that includes this?
> &gt; 
> &gt; 
> &gt; generic
> &gt;     with generic
> &gt;         with procedure Process(Set : in out Set_Type);
> &gt;     procedure Update(Set : in out Set_Type);
> &gt; package Set_Signature is end;
> &gt; 
> &gt; 
> &gt; Is not allowed. Is there some way to do this with nested packages?
> 
> There&#39;s no such thing as &quot;with generic&quot; in Ada.  That is, there is no way to set things up so that you can instantiate a generic like this:
> 
>    package An_Instantiation is new A_Generic (G1);
> 
> where G1 is the name of a *generic* subprogram or package.  Nor can I think of a reason why you&#39;d want to.  Perhaps if you gave us an example of what you&#39;re trying to accomplish?
> 
>                               -- Adam


Why would you want to? Easy... You use signature packages to decouple the implementation from the interface, so that other packages can decide which implementation to use.

Lets say we have two disjoint-set implementations, an Eager_Disjointset and a WUQPC_Disjointset. Both of these share a common interface, which we want to enforce so we declare a separate signature package Disjointset_Signature to describe this common interface.

The algorithms that use Disjointset are written using 


generic
    with package Disjointset is new Disjointset_Signature (<>);
package X is begin


So they can be compiled only 'with' the Disjointset_Signature package.


The final code which uses the algorithm can choose which container implementation to use by:

    package My_Disjointset is new Eager_Disjointset;
    use My_Disjointset;
    package My_Disjointset_Spec is new Disjointset_Signature(
        Set_Type => My_Disjointset.Set_Type
    );
    procedure My_Algorithm is new Algorithm(
        Disjointset_Spec => My_Disjointset_Spec
    );

But another part of the code could use the same algorithm with a different implementation of the container.


The problem comes implementing a function to mutate (update in place) data stored in the container. Maybe we want to implement:

procedure Update(
    Set : in out Set_Type;
    Index : in Index_Type;
    Process : access procedure(
        Element : in out Element_Type
    )
);

But this is slow because the procedure has to be passed as an access and cannot be inlined. So instead we try:

generic
    with procedure Process(
        Element : in out Element_Type;
    );
procedure Update(
    Set : in out Set_Type;
    Index : in Set_Index
);

This is good because 'Process' can be inlined, however how do we express this in the Signature package that represents the interface to these packages?


In the code that uses this we want to instantiate the generic with the relevant Process procedure, without referencing which implementation of Disjointset will eventually be used.

procedure Algorithm(Set : in out Set_Type) is
    procedure My_Process(Element : in out Element_Type) (
        ...
    );
    My_Update is new Update(Process => My_Process);
begin
    for J of Set loop
        My_Update(Set, J);
    end loop;
end Algorithm;


Cheers,
Keean.



  parent reply	other threads:[~2012-07-26 15:35 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <045f7b44-2a4a-4292-80fd-0b6bc8ee3465@googlegroups.com>
2012-07-21 22:22 ` Signature Package With Generic Proceedure Adam Beneschan
2012-07-22  7:28   ` Dmitry A. Kazakov
2012-07-22 16:22   ` Keean Schupke [this message]
2012-07-23  0:45     ` Adam Beneschan
     [not found]       ` <79925d0c-b2dd-44a3-9451-48f0ee19485f@googlegroups.com>
     [not found]         ` <500d3a9d$0$6566$9b4e6d93@newsspool4.arcor-online.net>
2012-07-23 18:29           ` Keean Schupke
     [not found]         ` <ac8bfaed-dbcc-491a-a760-c25672445eef@googlegroups.com>
2012-07-23 19:41           ` Keean Schupke
2012-07-24  2:57         ` Randy Brukardt
     [not found]         ` <jul2n4$af5$1@munin.nbi.dk>
2012-07-24  8:02           ` Keean Schupke
2012-07-24  8:43             ` Dmitry A. Kazakov
2012-07-24  8:59               ` Keean Schupke
2012-07-23 10:26 ` Simon Wright
2012-07-23 18:36   ` Keean Schupke
replies disabled

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