comp.lang.ada
 help / color / mirror / Atom feed
* Renaming of procedures in a generic instantiation
@ 2010-09-26  0:43 Gene
  2010-09-26  6:54 ` Niklas Holsti
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Gene @ 2010-09-26  0:43 UTC (permalink / raw)


I'm confused about an aspect of renaming. It boils out to this little
example:

with Ada.Containers.Ordered_Sets;

package Foo is

  type Queue is private;

  procedure Add(Q : in out Queue; Item : in Integer);

  function Is_Empty(Q : Queue) return Boolean;

private

  package Queues is
    new Ada.Containers.Ordered_Sets(Integer, "<", "=");
  type Queue is new Queues.Set with null record;

end Foo;

package body Foo is

   procedure Add(Q : in out Queue; Item : in Integer)
      renames Insert;

   function Is_Empty(Q : Queue) return Boolean
      renames Queues.Is_Empty;

end Foo;

The renaming in Add "finds" the correct procedure Insert, but the
renaming of Is_Empty fails:

gnatmake foo.adb
gcc -c foo.adb
foo.adb:6:04: no visible subprogram matches the specification for
"Is_Empty"
foo.adb:6:13: expected private type "Ada.Containers.Ordered_Sets.Set"
from insta
nce at foo.ads:14
foo.adb:6:13: found type "Queue" defined at foo.ads:16
gnatmake: "foo.adb" compilation error

I guess I can see this error because a parameter type conversion is
implied in the renaming.  But then why does the renaming of Insert
work correctly?

Running Win7 64 bit with:
gcc (GCC) 4.3.4 20090511 for GNAT GPL 2009 (20090511)

Thanks.



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

* Re: Renaming of procedures in a generic instantiation
  2010-09-26  0:43 Renaming of procedures in a generic instantiation Gene
@ 2010-09-26  6:54 ` Niklas Holsti
  2010-09-26  7:40   ` Jeffrey Carter
  2010-09-26 14:52   ` Gene
  2010-09-26  8:45 ` Stephen Leake
  2010-09-27 19:23 ` Adam Beneschan
  2 siblings, 2 replies; 13+ messages in thread
From: Niklas Holsti @ 2010-09-26  6:54 UTC (permalink / raw)


Gene wrote:
> I'm confused about an aspect of renaming. It boils out to this little
> example:
> 
> with Ada.Containers.Ordered_Sets;
> 
> package Foo is
> 
>   type Queue is private;
> 
>   procedure Add(Q : in out Queue; Item : in Integer);
> 
>   function Is_Empty(Q : Queue) return Boolean;
> 
> private
> 
>   package Queues is
>     new Ada.Containers.Ordered_Sets(Integer, "<", "=");
>   type Queue is new Queues.Set with null record;
> 
> end Foo;
> 
> package body Foo is
> 
>    procedure Add(Q : in out Queue; Item : in Integer)
>       renames Insert;
> 
>    function Is_Empty(Q : Queue) return Boolean
>       renames Queues.Is_Empty;
> 
> end Foo;
> 
> The renaming in Add "finds" the correct procedure Insert, but the
> renaming of Is_Empty fails:
> 
> gnatmake foo.adb
> gcc -c foo.adb
> foo.adb:6:04: no visible subprogram matches the specification for
> "Is_Empty"
> foo.adb:6:13: expected private type "Ada.Containers.Ordered_Sets.Set"
> from insta
> nce at foo.ads:14
> foo.adb:6:13: found type "Queue" defined at foo.ads:16
> gnatmake: "foo.adb" compilation error
> 
> I guess I can see this error because a parameter type conversion is
> implied in the renaming.  But then why does the renaming of Insert
> work correctly?

The type derivation

   type Queue is new Queues.Set with null record;

makes type Queue inherit the primitive operations of Queues.Set by 
implicitly declaring (within package Foo) corresponding operations on 
type Queue. These include the operation Insert with the profile:

    procedure Insert (
       Container : in out Queue;
       New_Item  : in     Integer);

This profile matches that of Foo.Add, and so Foo.Add can be a renaming 
of this Insert. By the way, this implicitly declared Insert (on Queue) 
has the qualified name Foo.Insert, not Queues.Insert.

The type derivation also "tries" to declare implicitly the Is_Empty 
operation from Queues, with the profile:

    function Is_Empty (Container : Queue) return Boolean;

but this operation clashes with (has the same name and same profile as) 
the operation Is_Empty that was already and explicitly declared in Foo 
(before the "private"), so they cannot both be visible. If I understand 
correctly, the rule RM 8.3(10/1) says that the first, explicit 
declaration overrides the second, implicit declaration (because the 
first declaration is not "overridable").

So what saves you in the Insert/Add case is that the operation names are 
different, which means there is no clash. It is a bit irritating that 
the "simpler" case, with the same names, does not work in the same way.

I have at times had the same problem, where I have been disappointed 
that implementing a private type as a derived type does not implicitly 
complete the declarations of matching operations, such as Is_Empty in 
this example. I would have liked to be able to write something like:

    type Queue is new Queues.Set with null record
       overriding Is_Empty (Q : Queue) return Boolean;  -- Not Ada!

No doubt you have already found a solution for Is_Empty, but anyway here 
is what I would do:

    function Is_Empty (Q : Queue) return Boolean
    is
    begin
       return Queues.Is_Empty (Queues.Set (Q));
    end Is_Empty;

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



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

* Re: Renaming of procedures in a generic instantiation
  2010-09-26  6:54 ` Niklas Holsti
@ 2010-09-26  7:40   ` Jeffrey Carter
  2010-09-26  8:41     ` Niklas Holsti
  2010-09-26 14:52   ` Gene
  1 sibling, 1 reply; 13+ messages in thread
From: Jeffrey Carter @ 2010-09-26  7:40 UTC (permalink / raw)


On 09/25/2010 11:54 PM, Niklas Holsti wrote:
>
> No doubt you have already found a solution for Is_Empty, but anyway here
> is what I would do:
>
> function Is_Empty (Q : Queue) return Boolean
> is
> begin
> return Queues.Is_Empty (Queues.Set (Q));
> end Is_Empty;

Or change the name of the operation (Empty comes to mind). I would probably use 
a wrapper record:

type Queue_Handle is
    Value : Queues.Set;
end record;

procedure Put (Onto : in out Queue_Handle; Item : in Integer) is
    -- null;
begin -- Put
    Onto.Insert (New_Item => Item);
end Put;

function Is_Empty (Queue : in Queue_Handle) is
    -- null;
begin -- Is_Empty
    return Queue.Value.Is_Empty;
end Is_Empty;

-- 
Jeff Carter
"We'll make Rock Ridge think it's a chicken
that got caught in a tractor's nuts!"
Blazing Saddles
87



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

* Re: Renaming of procedures in a generic instantiation
  2010-09-26  7:40   ` Jeffrey Carter
@ 2010-09-26  8:41     ` Niklas Holsti
  2010-09-26 17:07       ` Jeffrey Carter
  0 siblings, 1 reply; 13+ messages in thread
From: Niklas Holsti @ 2010-09-26  8:41 UTC (permalink / raw)


Jeffrey Carter wrote:
> On 09/25/2010 11:54 PM, Niklas Holsti wrote:
>>
>> No doubt you have already found a solution for Is_Empty, but anyway here
>> is what I would do:
>>
>> function Is_Empty (Q : Queue) return Boolean
>> is
>> begin
>> return Queues.Is_Empty (Queues.Set (Q));
>> end Is_Empty;
> 
> Or change the name of the operation (Empty comes to mind). I would 
> probably use a wrapper record:
> 
> type Queue_Handle is
>    Value : Queues.Set;
> end record;
> 
> procedure Put (Onto : in out Queue_Handle; Item : in Integer) is
>    -- null;
> begin -- Put
>    Onto.Insert (New_Item => Item);

A nit: You surely meant

      Onto.Value.Insert (New_Item => Item);

> end Put;
> 
> function Is_Empty (Queue : in Queue_Handle) is
>    -- null;
> begin -- Is_Empty
>    return Queue.Value.Is_Empty;
> end Is_Empty;
> 


-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



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

* Re: Renaming of procedures in a generic instantiation
  2010-09-26  0:43 Renaming of procedures in a generic instantiation Gene
  2010-09-26  6:54 ` Niklas Holsti
@ 2010-09-26  8:45 ` Stephen Leake
  2010-09-26  9:11   ` Niklas Holsti
  2010-09-27  1:18   ` Gene
  2010-09-27 19:23 ` Adam Beneschan
  2 siblings, 2 replies; 13+ messages in thread
From: Stephen Leake @ 2010-09-26  8:45 UTC (permalink / raw)


Gene <gene.ressler@gmail.com> writes:

> I'm confused about an aspect of renaming. It boils out to this little
> example:
>
> with Ada.Containers.Ordered_Sets;
>
> package Foo is
>
>   type Queue is private;
>
>   procedure Add(Q : in out Queue; Item : in Integer);
>
>   function Is_Empty(Q : Queue) return Boolean;
>
> private
>
>   package Queues is
>     new Ada.Containers.Ordered_Sets(Integer, "<", "=");
>   type Queue is new Queues.Set with null record;

All primitive operations of Queues.Set are implicitly declared here,
with Queue replacing Queues.Set; that includes Set and Is_Empty. That's
what derived types are for.

> end Foo;
>
> package body Foo is
>
>    procedure Add(Q : in out Queue; Item : in Integer)
>       renames Insert;

This 'Insert' resolves to Foo.Insert (Container : in out Foo.Queue; ...);

>    function Is_Empty(Q : Queue) return Boolean
>       renames Queues.Is_Empty;

Queues.Is_Empty expects a Constainer of type Foo.Queues.Set, not Foo.Queue.

If you replace 

   type Queue is new Queues.Set with null record;

with 

   subtype Queue is Queues.Set;

Then the Add renames will fail (because the primitive operations are not
derived), and the Is_Empty will succeed.

-- 
-- Stephe



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

* Re: Renaming of procedures in a generic instantiation
  2010-09-26  8:45 ` Stephen Leake
@ 2010-09-26  9:11   ` Niklas Holsti
  2010-09-27  1:18   ` Gene
  1 sibling, 0 replies; 13+ messages in thread
From: Niklas Holsti @ 2010-09-26  9:11 UTC (permalink / raw)


Stephen Leake wrote:
> Gene <gene.ressler@gmail.com> writes:
> 
>> I'm confused about an aspect of renaming. It boils out to this little
>> example:
>>
>> with Ada.Containers.Ordered_Sets;
>>
>> package Foo is
>>
>>   type Queue is private;
>>
>>   procedure Add(Q : in out Queue; Item : in Integer);
>>
>>   function Is_Empty(Q : Queue) return Boolean;
>>
>> private
>>
>>   package Queues is
>>     new Ada.Containers.Ordered_Sets(Integer, "<", "=");
>>   type Queue is new Queues.Set with null record;
> 
> All primitive operations of Queues.Set are implicitly declared here,
> with Queue replacing Queues.Set; that includes Set and Is_Empty. That's
> what derived types are for.
> 
>> end Foo;
>>
>> package body Foo is
>>
>>    procedure Add(Q : in out Queue; Item : in Integer)
>>       renames Insert;
> 
> This 'Insert' resolves to Foo.Insert (Container : in out Foo.Queue; ...);
> 
>>    function Is_Empty(Q : Queue) return Boolean
>>       renames Queues.Is_Empty;
> 
> Queues.Is_Empty expects a Constainer of type Foo.Queues.Set, not Foo.Queue.
> 
> If you replace 
> 
>    type Queue is new Queues.Set with null record;
> 
> with 
> 
>    subtype Queue is Queues.Set;
> 
> Then the Add renames will fail (because the primitive operations are not
> derived), and the Is_Empty will succeed.

But the subtype declaration of Queue cannot complete the initial 
declaration of Queue as private, so the subtype declaration must be the 
first and only (and public) declaration of type Queue.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



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

* Re: Renaming of procedures in a generic instantiation
  2010-09-26  6:54 ` Niklas Holsti
  2010-09-26  7:40   ` Jeffrey Carter
@ 2010-09-26 14:52   ` Gene
  2010-09-26 15:04     ` Dmitry A. Kazakov
  1 sibling, 1 reply; 13+ messages in thread
From: Gene @ 2010-09-26 14:52 UTC (permalink / raw)


On Sep 26, 2:54 am, Niklas Holsti <niklas.hol...@tidorum.invalid>
wrote:
> Gene wrote:
> > I'm confused about an aspect of renaming. It boils out to this little
> > example:
>
> > with Ada.Containers.Ordered_Sets;
>
> > package Foo is
>
> >   type Queue is private;
>
> >   procedure Add(Q : in out Queue; Item : in Integer);
>
> >   function Is_Empty(Q : Queue) return Boolean;
>
> > private
>
> >   package Queues is
> >     new Ada.Containers.Ordered_Sets(Integer, "<", "=");
> >   type Queue is new Queues.Set with null record;
>
> > end Foo;
>
> > package body Foo is
>
> >    procedure Add(Q : in out Queue; Item : in Integer)
> >       renames Insert;
>
> >    function Is_Empty(Q : Queue) return Boolean
> >       renames Queues.Is_Empty;
>
> > end Foo;
>
> > The renaming in Add "finds" the correct procedure Insert, but the
> > renaming of Is_Empty fails:
>
> > gnatmake foo.adb
> > gcc -c foo.adb
> > foo.adb:6:04: no visible subprogram matches the specification for
> > "Is_Empty"
> > foo.adb:6:13: expected private type "Ada.Containers.Ordered_Sets.Set"
> > from insta
> > nce at foo.ads:14
> > foo.adb:6:13: found type "Queue" defined at foo.ads:16
> > gnatmake: "foo.adb" compilation error
>
> > I guess I can see this error because a parameter type conversion is
> > implied in the renaming.  But then why does the renaming of Insert
> > work correctly?
>
> The type derivation
>
>    type Queue is new Queues.Set with null record;
>
> makes type Queue inherit the primitive operations of Queues.Set by
> implicitly declaring (within package Foo) corresponding operations on
> type Queue. These include the operation Insert with the profile:
>
>     procedure Insert (
>        Container : in out Queue;
>        New_Item  : in     Integer);
>
> This profile matches that of Foo.Add, and so Foo.Add can be a renaming
> of this Insert. By the way, this implicitly declared Insert (on Queue)
> has the qualified name Foo.Insert, not Queues.Insert.
>
> The type derivation also "tries" to declare implicitly the Is_Empty
> operation from Queues, with the profile:
>
>     function Is_Empty (Container : Queue) return Boolean;
>
> but this operation clashes with (has the same name and same profile as)
> the operation Is_Empty that was already and explicitly declared in Foo
> (before the "private"), so they cannot both be visible. If I understand
> correctly, the rule RM 8.3(10/1) says that the first, explicit
> declaration overrides the second, implicit declaration (because the
> first declaration is not "overridable").
>
> So what saves you in the Insert/Add case is that the operation names are
> different, which means there is no clash. It is a bit irritating that
> the "simpler" case, with the same names, does not work in the same way.
>
> I have at times had the same problem, where I have been disappointed
> that implementing a private type as a derived type does not implicitly
> complete the declarations of matching operations, such as Is_Empty in
> this example. I would have liked to be able to write something like:
>
>     type Queue is new Queues.Set with null record
>        overriding Is_Empty (Q : Queue) return Boolean;  -- Not Ada!
>
> No doubt you have already found a solution for Is_Empty, but anyway here
> is what I would do:
>
>     function Is_Empty (Q : Queue) return Boolean
>     is
>     begin
>        return Queues.Is_Empty (Queues.Set (Q));
>     end Is_Empty;
>
> --
> Niklas Holsti
> Tidorum Ltd
> niklas holsti tidorum fi
>        .      @       .- Hide quoted text -

Thanks for the clear and quick explanation.  It makes sense, but, as
you say, is a bit unsatisfying.  I've run into several cases where I
want to implement an abstraction with minor reshaping and restriction
of an Ada.Containers instance.  (The current one is event queues for a
simulator.)  As you've shown above, there are some quirks in this
approach.




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

* Re: Renaming of procedures in a generic instantiation
  2010-09-26 14:52   ` Gene
@ 2010-09-26 15:04     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 13+ messages in thread
From: Dmitry A. Kazakov @ 2010-09-26 15:04 UTC (permalink / raw)


On Sun, 26 Sep 2010 07:52:58 -0700 (PDT), Gene wrote:

> I've run into several cases where I
> want to implement an abstraction with minor reshaping and restriction
> of an Ada.Containers instance.  (The current one is event queues for a
> simulator.)  As you've shown above, there are some quirks in this
> approach.

Delegation (in order to implement interfaces) is poorly supported in Ada.
In real projects we have huge problems with this. About 40% of the code are
wrappers, nasty, error prone, incredibly difficult to maintain.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: Renaming of procedures in a generic instantiation
  2010-09-26  8:41     ` Niklas Holsti
@ 2010-09-26 17:07       ` Jeffrey Carter
  0 siblings, 0 replies; 13+ messages in thread
From: Jeffrey Carter @ 2010-09-26 17:07 UTC (permalink / raw)


On 09/26/2010 01:41 AM, Niklas Holsti wrote:
> Jeffrey Carter wrote:
>>
>> type Queue_Handle is
>>    Value : Queues.Set;
>> end record;
>>
>> procedure Put (Onto : in out Queue_Handle; Item : in Integer) is
>>    -- null;
>> begin -- Put
>>    Onto.Insert (New_Item => Item);
>
> A nit: You surely meant
>
> Onto.Value.Insert (New_Item => Item);

Yes, of course. Luckily, the compiler catches these for you.

-- 
Jeff Carter
"It's symbolic of his struggle against reality."
Monty Python's Life of Brian
78



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

* Re: Renaming of procedures in a generic instantiation
  2010-09-26  8:45 ` Stephen Leake
  2010-09-26  9:11   ` Niklas Holsti
@ 2010-09-27  1:18   ` Gene
  2010-09-28 11:36     ` Stephen Leake
  1 sibling, 1 reply; 13+ messages in thread
From: Gene @ 2010-09-27  1:18 UTC (permalink / raw)


On Sep 26, 4:45 am, Stephen Leake <stephen_le...@stephe-leake.org>
wrote:
> Gene <gene.ress...@gmail.com> writes:
> > I'm confused about an aspect of renaming. It boils out to this little
> > example:
>
> > with Ada.Containers.Ordered_Sets;
>
> > package Foo is
>
> >   type Queue is private;
>
> >   procedure Add(Q : in out Queue; Item : in Integer);
>
> >   function Is_Empty(Q : Queue) return Boolean;
>
> > private
>
> >   package Queues is
> >     new Ada.Containers.Ordered_Sets(Integer, "<", "=");
> >   type Queue is new Queues.Set with null record;
>
> All primitive operations of Queues.Set are implicitly declared here,
> with Queue replacing Queues.Set; that includes Set and Is_Empty. That's
> what derived types are for.
>
> > end Foo;
>
> > package body Foo is
>
> >    procedure Add(Q : in out Queue; Item : in Integer)
> >       renames Insert;
>
> This 'Insert' resolves to Foo.Insert (Container : in out Foo.Queue; ...);
>
> >    function Is_Empty(Q : Queue) return Boolean
> >       renames Queues.Is_Empty;
>
> Queues.Is_Empty expects a Constainer of type Foo.Queues.Set, not Foo.Queue.
>
> If you replace
>
>    type Queue is new Queues.Set with null record;
>
> with
>
>    subtype Queue is Queues.Set;
>
> Then the Add renames will fail (because the primitive operations are not
> derived), and the Is_Empty will succeed.
>
> --
> -- Stephe- Hide quoted text -
>
> - Show quoted text -

Thanks.  This is one variation I tried.  There is first a compiler
complaint that this private subtype declaration doesn't match the
earlier public "type Queue is private".  I take it there is no way at
all to declare a type private and then specify it in the private
section as a subtype?



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

* Re: Renaming of procedures in a generic instantiation
  2010-09-26  0:43 Renaming of procedures in a generic instantiation Gene
  2010-09-26  6:54 ` Niklas Holsti
  2010-09-26  8:45 ` Stephen Leake
@ 2010-09-27 19:23 ` Adam Beneschan
  2 siblings, 0 replies; 13+ messages in thread
From: Adam Beneschan @ 2010-09-27 19:23 UTC (permalink / raw)


On Sep 25, 5:43 pm, Gene <gene.ress...@gmail.com> wrote:
> I'm confused about an aspect of renaming. It boils out to this little
> example:
>
> with Ada.Containers.Ordered_Sets;
>
> package Foo is
>
>   type Queue is private;
>
>   procedure Add(Q : in out Queue; Item : in Integer);
>
>   function Is_Empty(Q : Queue) return Boolean;
>
> private
>
>   package Queues is
>     new Ada.Containers.Ordered_Sets(Integer, "<", "=");
>   type Queue is new Queues.Set with null record;
>
> end Foo;
>
> package body Foo is
>
>    procedure Add(Q : in out Queue; Item : in Integer)
>       renames Insert;
>
>    function Is_Empty(Q : Queue) return Boolean
>       renames Queues.Is_Empty;
>
> end Foo;
>
> The renaming in Add "finds" the correct procedure Insert, but the
> renaming of Is_Empty fails:
>
> gnatmake foo.adb
> gcc -c foo.adb
> foo.adb:6:04: no visible subprogram matches the specification for
> "Is_Empty"
> foo.adb:6:13: expected private type "Ada.Containers.Ordered_Sets.Set"
> from insta
> nce at foo.ads:14
> foo.adb:6:13: found type "Queue" defined at foo.ads:16
> gnatmake: "foo.adb" compilation error
>
> I guess I can see this error because a parameter type conversion is
> implied in the renaming.  But then why does the renaming of Insert
> work correctly?

Because you didn't refer to the "Insert" defined in Queues, the way
you did with Is_Empty.  If you had declared this, it would be illegal
in the same way:

   procedure Add(Q : in out Queue; Item : in Integer)
      renames Queues.Insert;

Obviously, you can't solve the problem for Is_Empty by removing the
"Queues." prefix:

   function Is_Empty(Q : in out Queue) return Boolean
      renames Is_Empty;

I found that this compiles, but it's obnoxious:

with Ada.Containers.Ordered_Sets;
package Foo is
  type Queue is private;
  procedure Add(Q : in out Queue; Item : in Integer);
  function Is_Empty(Q : Queue) return Boolean;
private
  package Queues is
    new Ada.Containers.Ordered_Sets(Integer, "<", "=");
  package Dummy_Package is
    type Dummy_Queue is new Queues.Set with null record;
    function Rename_Empty(Q : Dummy_Queue) return Boolean
      renames Is_Empty;
  end Dummy_Package;
  type Queue is new Dummy_Package.Dummy_Queue with null record;
end Foo;

package body Foo is
   procedure Add(Q : in out Queue; Item : in Integer)
      renames Insert;

   function Is_Empty(Q : Queue) return Boolean
      renames Rename_Empty;
end Foo;

Just writing Is_Empty to call Queues.Is_Empty, as Niklas suggested,
seems better than this.  I'd also add "pragma Inline(Is_Empty)" to the
private part of Foo to possibly prevent extraneous call code from
being generated.

I had thought that someone (possibly me) once proposed adding the
ability to declare that a subprogram renames the hidden subprogram
that it overrides, e.g.

   function Is_Empty(Q : Queue) return Boolean renames <>;

but I can't find anything like that in my mail records.  Randy did
once mention using something like Is_Empty'Parent as a stand-in for
the call to the parent routine; he wasn't thinking of a renaming
context, but it might work here:

   function Is_Empty(Q : Queue) return Boolean renames
Is_Empty'Parent;

In any event, however, it seems to be a minor enough problem with a
simple enough workaround that it's not worthwhile to change the
language.

                            -- Adam









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

* Re: Renaming of procedures in a generic instantiation
  2010-09-27  1:18   ` Gene
@ 2010-09-28 11:36     ` Stephen Leake
  2010-09-29  1:25       ` Gene
  0 siblings, 1 reply; 13+ messages in thread
From: Stephen Leake @ 2010-09-28 11:36 UTC (permalink / raw)


Gene <gene.ressler@gmail.com> writes:

> Thanks.  This is one variation I tried.  There is first a compiler
> complaint that this private subtype declaration doesn't match the
> earlier public "type Queue is private".  I take it there is no way at
> all to declare a type private and then specify it in the private
> section as a subtype?

Ah; I had not realized the original problem you were having; how to
implement the body for Is_Empty. The simplest approach is this:

with Ada.Containers.Ordered_Sets;
package Foo is
  type Queue is private;
  procedure Add(Q : in out Queue; Item : in Integer);
  function Is_Empty(Q : Queue) return Boolean;
private
  package Queues is
    new Ada.Containers.Ordered_Sets(Integer, "<", "=");
  type Queue is new Queues.Set with null record;
end Foo;
package body Foo is
   procedure Add(Q : in out Queue; Item : in Integer)
      renames Insert;

   function Is_Empty(Q : Queue) return Boolean
   is begin
      return Queues.Is_Empty (Queues.Set (Q));
   end Is_Empty;
end Foo;

-- 
-- Stephe



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

* Re: Renaming of procedures in a generic instantiation
  2010-09-28 11:36     ` Stephen Leake
@ 2010-09-29  1:25       ` Gene
  0 siblings, 0 replies; 13+ messages in thread
From: Gene @ 2010-09-29  1:25 UTC (permalink / raw)


On Sep 28, 7:36 am, Stephen Leake <stephen_le...@stephe-leake.org>
wrote:
> Gene <gene.ress...@gmail.com> writes:
> > Thanks.  This is one variation I tried.  There is first a compiler
> > complaint that this private subtype declaration doesn't match the
> > earlier public "type Queue is private".  I take it there is no way at
> > all to declare a type private and then specify it in the private
> > section as a subtype?
>
> Ah; I had not realized the original problem you were having; how to
> implement the body for Is_Empty. The simplest approach is this:
>
> with Ada.Containers.Ordered_Sets;
> package Foo is
>   type Queue is private;
>   procedure Add(Q : in out Queue; Item : in Integer);
>   function Is_Empty(Q : Queue) return Boolean;
> private
>   package Queues is
>     new Ada.Containers.Ordered_Sets(Integer, "<", "=");
>   type Queue is new Queues.Set with null record;
> end Foo;
> package body Foo is
>    procedure Add(Q : in out Queue; Item : in Integer)
>       renames Insert;
>
>    function Is_Empty(Q : Queue) return Boolean
>    is begin
>       return Queues.Is_Empty (Queues.Set (Q));
>    end Is_Empty;
> end Foo;
>
> --
> -- Stephe

Right.  Thanks. Understood that from the outset. Was just scratching
my head because Insert could be defined by renaming, but there was no
way to do the same for Is_Empty owing to the name clash.  I thought
there had to be some dot-path that would work.  In fact the only
recourses (using renaming) seem to be either to choose another name
for the public Is_Empty or to use the ingenous but truly crufty double
renaming trick shown by Adam Beneschan.

FWIW, I'm working out a framework for a student project, so the desire
for symmetry in the code is more pedantic than esthetic or anything
else.

Thanks guys.




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

end of thread, other threads:[~2010-09-29  1:25 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-26  0:43 Renaming of procedures in a generic instantiation Gene
2010-09-26  6:54 ` Niklas Holsti
2010-09-26  7:40   ` Jeffrey Carter
2010-09-26  8:41     ` Niklas Holsti
2010-09-26 17:07       ` Jeffrey Carter
2010-09-26 14:52   ` Gene
2010-09-26 15:04     ` Dmitry A. Kazakov
2010-09-26  8:45 ` Stephen Leake
2010-09-26  9:11   ` Niklas Holsti
2010-09-27  1:18   ` Gene
2010-09-28 11:36     ` Stephen Leake
2010-09-29  1:25       ` Gene
2010-09-27 19:23 ` Adam Beneschan

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