From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00,FORGED_GMAIL_RCVD, FREEMAIL_FROM,WEIRD_PORT autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,79d6bba6ba97b840 X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII Path: g2news1.google.com!news2.google.com!postnews.google.com!a36g2000yqc.googlegroups.com!not-for-mail From: Gene Newsgroups: comp.lang.ada Subject: Re: Renaming of procedures in a generic instantiation Date: Sun, 26 Sep 2010 07:52:58 -0700 (PDT) Organization: http://groups.google.com Message-ID: References: <8g890nFmqiU1@mid.individual.net> NNTP-Posting-Host: 184.12.85.212 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1285512778 1585 127.0.0.1 (26 Sep 2010 14:52:58 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Sun, 26 Sep 2010 14:52:58 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: a36g2000yqc.googlegroups.com; posting-host=184.12.85.212; posting-account=-BkjswoAAACC3NU8b6V8c50JQ2JBOs04 User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; HPNTDF; .NET4.0C),gzip(gfe) Xref: g2news1.google.com comp.lang.ada:14272 Date: 2010-09-26T07:52:58-07:00 List-Id: On Sep 26, 2:54=A0am, Niklas Holsti 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 > > > =A0 type Queue is private; > > > =A0 procedure Add(Q : in out Queue; Item : in Integer); > > > =A0 function Is_Empty(Q : Queue) return Boolean; > > > private > > > =A0 package Queues is > > =A0 =A0 new Ada.Containers.Ordered_Sets(Integer, "<", "=3D"); > > =A0 type Queue is new Queues.Set with null record; > > > end Foo; > > > package body Foo is > > > =A0 =A0procedure Add(Q : in out Queue; Item : in Integer) > > =A0 =A0 =A0 renames Insert; > > > =A0 =A0function Is_Empty(Q : Queue) return Boolean > > =A0 =A0 =A0 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. =A0But then why does the renaming of Insert > > work correctly? > > The type derivation > > =A0 =A0type 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: > > =A0 =A0 procedure Insert ( > =A0 =A0 =A0 =A0Container : in out Queue; > =A0 =A0 =A0 =A0New_Item =A0: in =A0 =A0 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: > > =A0 =A0 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: > > =A0 =A0 type Queue is new Queues.Set with null record > =A0 =A0 =A0 =A0overriding Is_Empty (Q : Queue) return Boolean; =A0-- Not = Ada! > > No doubt you have already found a solution for Is_Empty, but anyway here > is what I would do: > > =A0 =A0 function Is_Empty (Q : Queue) return Boolean > =A0 =A0 is > =A0 =A0 begin > =A0 =A0 =A0 =A0return Queues.Is_Empty (Queues.Set (Q)); > =A0 =A0 end Is_Empty; > > -- > Niklas Holsti > Tidorum Ltd > niklas holsti tidorum fi > =A0 =A0 =A0 =A0. =A0 =A0 =A0@ =A0 =A0 =A0 .- 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.