[comp.lang.ada] Expanded names

Marc.Graham@SEI.CMU.EDU (09/25/90)

The following Ada code compiles cleanly and produces the output
"Inner". Question: Is there any way that the outer outer_constant may
be named from the inner testnames? If no, then why is 4.1.3 rule f (in
particular, para 18 and 19) worded the way it is? (Note: if the outer
testnames were a procedure, rather than a package, the expanded name
testnames.outer_context is illegal within the inner testnames.)
------------------------------------------------------------
package testnames is
    procedure testnames (outer_constant : integer);
end testnames;
with text_io; use text_io;
package body testnames is

    outer_constant : constant := 3.14159;
    
    procedure testnames (outer_constant : integer) is
    begin
    if testnames.outer_constant > 2 then
    	put_line("Outer!");
    else
    	put_line("Inner");
    end if;
    end testnames;
end testnames;
with testnames;
procedure exectest is
begin
    testnames.testnames(1);
end exectest;
------------------------------------------------------------

Marc H. Graham                    Software Engineering Institute
marc@sei.cmu.edu                  Carnegie Mellon University
(412) 268 7784                    Pittsburgh, PA   15213
                   

dik@cwi.nl (Dik T. Winter) (09/25/90)

In article <9009241814.AA08734@bx.sei.cmu.edu> Marc.Graham@SEI.CMU.EDU writes:
 > 
 >          Question: Is there any way that the outer outer_constant may
 > be named from the inner testnames?
Yes:
 > ....
First, to prevent a semantic error, change
 >     outer_constant : constant := 3.14159;
to
       outer_constant : constant := 4;
and next
 >     if testnames.outer_constant > 2 then
to
       if standard.testnames.outer_constant > 2 then
--
dik t. winter, cwi, amsterdam, nederland
dik@cwi.nl

NCOHEN@IBM.COM ("Norman H. Cohen") (09/26/90)

Marc Graham presents a library package TESTNAMES with the following
body:

   package body testnames is

       outer_constant : constant := 3.14159;

       procedure testnames (outer_constant : integer) is
       begin
          ... testnames.outer_constant ...
       end testnames;
   end testnames;

He observes that the occurrence of "testnames.outer_constant" in the
procedure body refers to the formal parameter, not the named number, and
asks whether there is any way to denote the named number from within
the procedure body.  Since all library units are considered to be
declared directly within package STANDARD, the name
STANDARD.TESTNAMES.OUTER_CONSTANT will work.  (See the notes in RM
8.6(3) and 10.1(10).)

Marc also asserts that if the outer TESTNAMES were a procedure rather
than a package, the expanded name TESTNAMES.OUTER_CONTEXT would be
illegal within the inner TESTNAMES, citing RM 4.1.3(18):

   If the prefix is the name of a subprogram or accept statement and
   there is more than one visible enclosing subprogram or accept
   statement of this name, the expanded name is ambiguous, independently
   of the selector.

The key word here is VISIBLE.  Marc's original example works as it does
because the inner declaration of TESTNAMES hides the outer declaration
throughout the immediate scope of the inner declaration (see 8.3(15)).
(Marc declares the TESTNAMES procedure within the TESTNAMES package
declaration, not shown above, so the package name is hidden from there
through the rest of the package declaration, as well as throughout the
package body.)  In the case of subprograms and accept statements,
overloading rules allow both an inner and an outer declaration of the
same name to be visible--if the parameter and result type profiles are
different.  Thus a special rule is provided.  (The alternative would
have been to use the innermost enclosing unit, but then 4.1.3(f) could
not have been phrased in terms of visibility rules.  Simplicity of
presentation was apparently chosen over uniform semantics for naming
enclosing units in prefixes, but the issue only arises in pathological
programs anyway.)  Here is a (suitably pathological) illustration:

   procedure P (X: in Integer) is     --P#1

      procedure P (X: in Float) is    --P#2
         -- Both P#1 and P#2 visible here since profiles are different
         ... P.X ... -- Illegal by RM 4.1.3(18)
      end P;

      procedure P (X: in Integer) is  --P#3
         -- P#1 is hidden by P#3 here.
         ... P.X ... -- Legal, refers to formal parameter of P#3.
      end P;

   end P;

Finally, Marc asks about RM 4.1.3(19), which concerns a completely
different pathology:  If F is a parameterless function returning a
record value with component C, then within a unit named F, the name
F.C could be interpreted either as a call on the function followed by
selection of the record component (which 4.1.3(19) explicitly excludes)
or as the name of an entity C declared immediately within unit F.

eachus@linus.mitre.org (Robert I. Eachus) (10/02/90)

     Of course if you replace the name testnames with STANDARD, now it
is impossible to name the outer outer_constant from the inner
STANDARD, but that carries this experiment to its most pathological
extreme.  (It it legal to compile a library package named STANDARD,
but not one named CHARACTER or INTEGER.  There seemed to be no need to
have a special rule to make such masochistic behavior explicitly
illegal.)

--

					Robert I. Eachus

with STANDARD_DISCLAIMER;
use  STANDARD_DISCLAIMER;
function MESSAGE (TEXT: in CLEVER_IDEAS) return BETTER_IDEAS is...