comp.lang.ada
 help / color / mirror / Atom feed
From: Gene <gene.ressler@gmail.com>
Subject: Re: Renaming of procedures in a generic instantiation
Date: Sun, 26 Sep 2010 07:52:58 -0700 (PDT)
Date: 2010-09-26T07:52:58-07:00	[thread overview]
Message-ID: <e4e20983-55a1-4a89-91b3-806f381843f6@a36g2000yqc.googlegroups.com> (raw)
In-Reply-To: 8g890nFmqiU1@mid.individual.net

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.




  parent reply	other threads:[~2010-09-26 14:52 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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
replies disabled

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