comp.lang.ada
 help / color / mirror / Atom feed
From: Adam Beneschan <adam@irvine.com>
Subject: Re: Recursive parameters in generics
Date: Tue, 24 Jul 2007 09:00:39 -0700
Date: 2007-07-24T09:00:39-07:00	[thread overview]
Message-ID: <1185292839.391337.258620@e16g2000pri.googlegroups.com> (raw)
In-Reply-To: <rb5r7qu72sgd$.19mpqecqgqzo8.dlg@40tude.net>

On Jul 24, 1:09 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Mon, 23 Jul 2007 14:51:10 -0700, Adam Beneschan wrote:
> > On Jul 23, 11:20 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> > wrote:
> >> Hi there,
>
> >> out of curiosity, recently experimenting with workarounds for generics, I
> >> invented a construct, which puzzles me. Is the following legal:
>
> >> generic
> >>    S : String;
> >> package A is
> >>    S_Of : String renames S;
> >> end A;
> >> -----------------------------------
> >> with A;
> >> generic
> >>    S : String;
> >>    with package This_A is new A (S => S);
> >> package B is
> >> end B;
> >> -----------------------------------
> >> with A;
> >> package My_A is new A (S => "whatever");
> >> -----------------------------------
> >> with My_A;
> >> with B;
> >> package My_B is
> >>    new B (This_A => My_A, S => My_A.S_Of);
> >> -----------------------------------
> >> One could think that My_B would take S_Of from an instance of A and then
> >> pass it back to A.
>
> > I don't see why this would be any different from
>
> > package My_B is new B (S => "whatever", This_A => My_A);
>
> So you think it is legal?

It should be.  However, I'm taking a second look at 12.7(5-6).

> > If you're thinking about My_B passing something back to A, you're
> > probably thinking about the whole problem sideways.  My_B doesn't
> > instantiate A at all, it uses an already-existing instance of A.
>
> I mean the process of matching parameters. I.e. what happens at the
> instantiation point. At least it perplexes GNAT, provided the thingy is
> legal.

The first formal parameter to B is "S : String", and you're matching
it with My_A.S_Of, which is the string "whatever".

The second formal parameter is "with package This_A is new A (S =>
S)";  This matches My_A as long as the S parameter of This_A and My_A
match.  The S parameter of This_A is the actual for S, which is
My_A.S_Of.  The "actual parameter of the actual instance" is the
actual parameter you gave when instantiating My_A, which is the string
literal "whatever".  So the question now is whether My_A.S_Of and
"whatever" statically denote the same constant, or are static
expressions with the same value (see 12.7(6)).

And this is where things get yucky.  12.3(13) says that an instance is
a copy of the text in the template, where each "use of a formal
parameter" becomes a "use of the actual"; but does this mean that in
the instance My_A, the use of "S" *statically denotes* (see
4.9(14-17)) the string literal "whatever"?  (If it did, then S_Of
would also denote the same string literal, by 4.9(17).)  If it does,
then I think the example is probably legal---but maybe not, since a
constant is an object, and a literal is a value, not a constant, and
I'm not clear on just what "object" would be denoted by My_A.S or
My_A.S_Of.

Just to complicate things, I tried this on GNAT, and also tried the
same example replacing String by Integer and the string literal by an
integer literal.  GNAT rejected the version with String but accepted
the version with Integer.  Offhand, I can't see any reason why the two
cases would be different, so I suspect there's a GNAT bug involved---
but whether it should be accepting the String case, or rejecting the
Integer case, I don't know.  (Also, I may not be using the latest
version of GNAT.)

To summarize my conclusions: (1) Your example *should* be legal, since
it seems like the actual parameter to the actual instance My_A, and
the actual parameter to the formal instance This_A, do refer to the
exact same object.  (2) The definitions in the RM seem too ambiguous
to know for certain whether the example is legal or not.  I may need
to examine this more carefully, though.  It may be that language needs
to be added to 4.9 to deal with generic formals in an instance (when
they're referred to outside of the instance).  Or it may be that the
RM language is already sufficient to deal with this, and I need to dig
deeper and find it.  (3) If it turns out that it isn't legal, this
seems like a hole in the language, since there doesn't seem to be any
reason why this shouldn't be allowed.  (4) GNAT probably is not
handling this correctly.

                           -- Adam






  reply	other threads:[~2007-07-24 16:00 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-23 18:20 Recursive parameters in generics Dmitry A. Kazakov
2007-07-23 19:32 ` Maciej Sobczak
2007-07-23 19:46   ` Dmitry A. Kazakov
2007-07-23 21:51 ` Adam Beneschan
2007-07-24  8:09   ` Dmitry A. Kazakov
2007-07-24 16:00     ` Adam Beneschan [this message]
2007-07-25  6:43       ` AW: " Grein, Christoph (Fa. ESG)
2007-07-25 15:13         ` 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