Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Declaring private packages to instantiate generics?

47 views
Skip to first unread message

Markus Schöpflin

unread,
May 16, 2012, 10:21:24 AM5/16/12
to
I just found myself wanting to write the following code, which Gnat doesn't like:

---%<---
package FOO is
procedure P;
end FOO;

package body FOO is
package BAR is new SOME_GENERIC_PACKAGE;
procedure P is new BAR.P;
end FOO;
--->%---

Can I somehow provide the body of P without writing a procedure which just
forwards to an instantiation of BAR.P, IOW without having to write:

---%<---
package body FOO is
package BAR is new SOME_GENERIC_PACKAGE;
procedure BAR_P is new BAR.P;
procedure P is begin BAR_P; end;
end FOO;
--->%---

Regards,
Markus

Adam Beneschan

unread,
May 16, 2012, 10:36:27 AM5/16/12
to
You can change the last to

procedure P renames BAR_P;

But that's the best you can do. If you have an incomplete declaration (i.e. the declaration of P in the *spec* of FOO), you can't complete it with a generic instantiation---that's the rule. (I think he reason is that a generic instantiation is equivalent to a declaration of the instance followed by the body of the instance, and doing that here would mean you're declaring P twice, which isn't allowed. It can be argued that the language rules should be relaxed in this case, since it's tripped up more than one person, and offhand I don't see any complications that would arise if it were allowed.)

-- Adam

Markus Schöpflin

unread,
May 16, 2012, 10:45:20 AM5/16/12
to
Am 16.05.2012 16:36, schrieb Adam Beneschan:

[...]

>> ---%<---
>> package body FOO is
>> package BAR is new SOME_GENERIC_PACKAGE;
>> procedure BAR_P is new BAR.P;
>> procedure P is begin BAR_P; end;
>> end FOO;
>> --->%---
>>
>> Regards,
>> Markus
>
> You can change the last to
>
> procedure P renames BAR_P;

Thanks for your answer. Not as nice as I had hoped, but basically what I was
looking for.

Markus

Shark8

unread,
May 16, 2012, 9:24:58 PM5/16/12
to
Why is using RENAMES not nice?
It seems that the only difference between using RENAMES and what you showed (procedure P is new BAR.P;) is the syntax.

Adam Beneschan

unread,
May 16, 2012, 11:37:02 PM5/16/12
to
On Wednesday, May 16, 2012 7:36:27 AM UTC-7, Adam Beneschan wrote:

> > package FOO is
> > procedure P;
> > end FOO;
> >
> > package body FOO is
> > package BAR is new SOME_GENERIC_PACKAGE;
> > procedure P is new BAR.P;
> > end FOO;
> > --->%---
> >
> > Can I somehow provide the body of P without writing a procedure which just
> > forwards to an instantiation of BAR.P, IOW without having to write:
> >
> > ---%<---
> > package body FOO is
> > package BAR is new SOME_GENERIC_PACKAGE;
> > procedure BAR_P is new BAR.P;
> > procedure P is begin BAR_P; end;
> > end FOO;
> > --->%---
> >
> > Regards,
> > Markus
>
> You can change the last to
>
> procedure P renames BAR_P;
>
> But that's the best you can do. If you have an incomplete declaration (i.e. the declaration of P in the *spec* of FOO), you can't complete it with a generic instantiation---that's the rule. (I think he reason is that a generic instantiation is equivalent to a declaration of the instance followed by the body of the instance, and doing that here would mean you're declaring P twice, which isn't allowed. It can be argued that the language rules should be relaxed in this case, since it's tripped up more than one person, and offhand I don't see any complications that would arise if it were allowed.)

I just got reminded by Tucker Taft that there's a problem if P has parameters. The parameters aren't listed in a generic_instantiation:

package FOO is
procedure P (Param : in Integer; Param2 : out Integer);
end FOO;

package body FOO is
package BAR is new SOME_GENERIC_PACKAGE;
procedure P is new BAR.P;
end FOO;

This makes it less clear to the eye that the second P completes the first one. (This would especially be a problem if there is more than one P with different parameter profiles in the specification.) This makes it clearer:

package FOO is
procedure P (Param : in Integer; Param2 : out Integer);
end FOO;

package body FOO is
package BAR is new SOME_GENERIC_PACKAGE;
procedure New_P is new BAR.P;
procedure P (Param : in Integer; Param2 : out Integer)
renames New_P;
end FOO;

So there's a good reason why the rules are the way they are.

-- Adam

Markus Schöpflin

unread,
May 21, 2012, 4:06:29 AM5/21/12
to
Am 17.05.2012 05:37, schrieb Adam Beneschan:
> On Wednesday, May 16, 2012 7:36:27 AM UTC-7, Adam Beneschan wrote:

[...]

> I just got reminded by Tucker Taft that there's a problem if P has
> parameters. The parameters aren't listed in a generic_instantiation:
>
> package FOO is procedure P (Param : in Integer; Param2 : out Integer); end
> FOO;
>
> package body FOO is package BAR is new SOME_GENERIC_PACKAGE; procedure P is
> new BAR.P; end FOO;
>
> This makes it less clear to the eye that the second P completes the first
> one. (This would especially be a problem if there is more than one P with
> different parameter profiles in the specification.) This makes it
> clearer:
>
> package FOO is procedure P (Param : in Integer; Param2 : out Integer); end
> FOO;
>
> package body FOO is package BAR is new SOME_GENERIC_PACKAGE; procedure
> New_P is new BAR.P; procedure P (Param : in Integer; Param2 : out Integer)
> renames New_P; end FOO;
>
> So there's a good reason why the rules are the way they are.

You're right, thanks for the follow-up. And it's even the case in my case, I
have a whole bunch of Ps which are implemented as instantiations of the same
procedure.

Markus

PS: Sorry for rewrapping your part of the mail but my NNTP server started to
complain about lines longer than 79 characters when posting.

Simon Wright

unread,
May 21, 2012, 11:51:03 AM5/21/12
to
Markus Schöpflin <no....@spam.spam> writes:

> PS: Sorry for rewrapping your part of the mail but my NNTP server
> started to complain about lines longer than 79 characters when
> posting.

I've done this for a long time as a matter of course. It's particularly
necessary now that Google Groups has stopped doing any line-wrap at all!
(and very easy using Emacs gnus - M-q).

I didn't think it was rude?
0 new messages