Version 1.1 of acs/ac-00104.txt

Unformatted version of acs/ac-00104.txt version 1.1
Other versions for file acs/ac-00104.txt

!standard 3.10.2(13)          04-11-14 AC95-00104/01
!class Amendment 04-11-14
!status received no action 04-11-14
!status received 04-09-26
!subject Accessibility of anonymous function results
!summary
!appendix

From: Tucker Taft
Sent: Saturday, September 25, 2004  2:52 PM

I'm wondering whether we can kill two birds with
one stone:

What if we make the accessibility
level for anonymous access return types "infinite"
depth, in the same way we do for anonymous
access-to-subp parameter types?  This would mean
that you pretty much have to use the result
immediately, or rename it, but you can't store
it away in a global without an Unchecked_Access.

This would also open up the feature to allow you
to safely return a reference into the middle of a data structure
(such as a vector), even if the vector is completely
represented on the stack, with no heap anywhere.

Thoughts?

[Aside: During the Ada 9X process we had proposed "limited"
access types for this purpose, but adding "limited"
somewhere into:

   type Rand_Ptr is
     not null access function return not null access constant T;

might finally sink the keyword ship. ;-) ]

P.S. Conceivably we could provide implicit dereference for
access types with infinite depth.  This would make the
ability to define an "abstract" array pretty nearly complete:

     type Abstract_Array(First, Last : Integer) is tagged private;

     function Elem(AA : access Abstract_Array; Index : Integer)
       return not null access Elem_Type;

   ...

     Arr : aliased Abstract_Array(1..10);

     X : Elem_Type := Arr.Elem(3);

   ...

     Arr.Elem(3) := Arr.Elem(3) + 2;

Robert A Duff wrote:

> Tucker said:
>>Leave it as is, in my view.  Safety over convenience, and
>>defining a procedure locally isn't that inconvenient, once
>>you get used to the idea.
>
>
> Well, I don't like dangling pointers, either, but I lean the other way
> on this one:  I think being forced to move a small hunk of code away
> from where I want it, wrap it in several lines of syntax, and clutter
> the namespace with a meaningless procedure name really IS a big pain.
> (That is, forcing the programmer to make an abstraction boundary at a
> place where it's inappropriate to do so.)
>
> I view this as "safety versus readability", not "safety versus
> convenience" -- and that makes the choice not so obvious.
> If you give me Lisp lambdas, I wouldn't mind the procedure approach.
> OTOH, if you give me C++ references, the ref approach could be safe
> (I think?).

****************************************************************

From: Robert A. Duff
Sent: Saturday, September 25, 2004  3:33 PM

> What if we make the accessibility
> level for anonymous access return types "infinite"
> depth, in the same way we do for anonymous
> access-to-subp parameter types?

Cool idea.

****************************************************************

From: Tucker Taft
Sent: Sunday, September 26, 2004  9:50 AM

Unfortunately, nothing is as simple as it sounds.
We would probably like to compose functions that
return anonymous access types, so we would need
some way to decide whether it was safe to have
one such function return the result of a call on
another such function.  This would argue for the
accessibility of the result being related to the
accessibility of the parameters (considering
tagged parameters, parameters with aliased parts,
and access parameters), or go back to having some
kind of accessibility level returned from such
a function (which has been difficult to define
in the past).

It's frustrating...

****************************************************************

From: Randy Brukardt
Sent: Monday, September 27, 2004  4:39 AM

I'm confused. The accessibility level applies to both sides of a return (the
return statement and the result of the function), just like it does to anon
access-to-subp parameters.

So infinite would match infinite (just like it does for anon access-to-subp
parameters). So any anon access function could return the result of another
anon access function. (And it couldn't return an anon access function as a
non-anon type, which is the entire point of the definition.) Where's the
problem?

I certainly can imagine that there is a problem in here somewhere, but I
haven't imagined it yet.

****************************************************************

From: Tucker Taft
Sent: Monday, September 27, 2004  4:53 PM

Did anyone have any interest in this idea?
I think it might be worth some investment, as
I think it would make returning an pointer into
a stack-allocated container safe.

It isn't as simple, but we might be able to find
something that works and is safer.  E.g.:

    The accessibility level of the result is the
    maximum of the accessibility level of the function,
    the accessibility level of any access parameters,
    and the accessibility level of any parameter with a
    tagged, aliased, or private part.

This would mean that the called function could return the
result of calling another function, and could return a pointer
into any of the parameters where 'Access is permitted.
The only thing the called function couldn't do is return
a 'Access of a locally declared object (obviously a bad idea!),
or the result of calling a nested function (which our existing
"simple" approach wouldn't allow either).

Comments?

****************************************************************

From: Randy Brukardt
Sent: Monday, September 27, 2004  5:10 PM

> Did anyone have any interest in this idea?

Yes, of course, or I wouldn't have responded to your message a few minutes
ago.

> I think it might be worth some investment, as
> I think it would make returning an pointer into
> a stack-allocated container safe.

Absolutely. I'd love to get rid of "Update_Element"'s Process procedure. But
we need that to be safe.

> It isn't as simple, but we might be able to find
> something that works and is safer.  E.g.:
>
>     The accessibility level of the result is the
>     maximum of the accessibility level of the function,
>     the accessibility level of any access parameters,
>     and the accessibility level of any parameter with a
>     tagged, aliased, or private part.

Ugh. This seems to be a runtime calculated level, as an access parameter's
level is determined by the actual. The wording sounds like you are also
using the level of the actuals to for "tagged, aliased, or private part".

> This would mean that the called function could return the
> result of calling another function, and could return a pointer
> into any of the parameters where 'Access is permitted.
> The only thing the called function couldn't do is return
> a 'Access of a locally declared object (obviously a bad idea!),
> or the result of calling a nested function (which our existing
> "simple" approach wouldn't allow either).
>
> Comments?

It certainly would be good to make returning local objects illegal, but I
don't see how this would do that. If the function had access parameters are
a deeper level than it is declared at, the level would be deeper than the
function itself and returning a local would be allowed.

I would be tempted to split the accessibility levels; it would be the level
of the function for the return statement (which would disallow local
objects) and it would be infinite to the caller, unless that caller was a
return statement for a function that returns anon access. In that case, the
level used would be the level of the function (which would disallow nested
anon returns, but allow more global ones).

****************************************************************

From: Robert A. Duff
Sent: Monday, September 27, 2004  7:18 PM

I haven't thought about the details.  But if it works, it sounds like a
wonderful idea to me.  I've been wanting a safe way to return pointers
to elements of data structures for years.  The existing workarounds are
either unsafe, or inefficient in many cases.

****************************************************************

From: Tucker Taft
Sent: Tuesday, September 28, 2004  11:16 AM

Did you see my attempt to define the accessibility
depth?  (The max of function itself and
params with a part that is access/aliased/tagged/private.)
Does this sound viable?

****************************************************************

From: Randy Brukardt
Sent: Tuesday, September 28, 2004  11:33 AM

Are you seeing my messages on this subject? I've responded at least twice
before this one!

Your solution is far too complex and worse, its dynamic (in that the level
cannot be determined at compile-time). And, if I understand it properly, it
doesn't work (see previous message).

All that is required is that a function not be able to return anything that
is declared locally (including function results). Anything that comes from
the outside of the function (anywhere, including parameters) is fine; it
will have to live as long as the result.

There's a number of ways to accomplish that (infinite accessibility + a
check similar to the return-by-reference one; split accessibility; etc.).

Perhaps that has some problem that I missed, but we need a fairly simple
solution or it isn't going to fly.

****************************************************************

From: Tucker Taft
Sent: Tuesday, September 28, 2004  12:21 PM

> Yes, of course, or I wouldn't have responded to your message a few minutes
> ago.

Sorry.  There seem to be some delays in the ARG list,
at least from my end.

> Ugh. This seems to be a runtime calculated level, as an access parameter's
> level is determined by the actual. The wording sounds like you are also
> using the level of the actuals to for "tagged, aliased, or private part".

Correct.  I agree it would be nice if it were static, but the
important thing to me is that it is easy to check at the point
of the return statement.  The basic rule at the return point
is that you can't return a reference to a local object.

> It certainly would be good to make returning local objects illegal, but I
> don't see how this would do that. If the function had access parameters are
> a deeper level than it is declared at, the level would be deeper than the
> function itself and returning a local would be allowed.

I think you are probably forgetting that accessibility levels
are defined to be the *dynamic* nesting levels.  We do have
rules about being statically more or less nested, but when
I say accessibility level, I mean the dynamic one.  Hopefully
the actual checks can usually be defined in terms of static
checks.

In any case, if you focus just on the dynamic level (and for
now put aside the expense of checking tdynamically), then clearly
an access parameter can't be at a deeper level than the local
variables of the called function.

> I would be tempted to split the accessibility levels; it would be the level
> of the function for the return statement (which would disallow local
> objects) and it would be infinite to the caller, unless that caller was a
> return statement for a function that returns anon access. In that case, the
> level used would be the level of the function (which would disallow nested
> anon returns, but allow more global ones).

I think it is quite important that one function with an anonymous
return type can return the result of calling another such function.
I'll see if I can elaborate on the suggested wording and provide
an implementation model.  The basic rule, from a user's model,
is that a function cannot return a reference to a local object.
That seems relatively intuitive.  What I am looking for is a rule
that does *not* require the called function to return an accessibility
level, but still provides maximum flexibility.  The caller needs to
assume that the called function might return a pointer into any
object passed in where 'Access is legal, or it might return an
access parameter, or 'Access of a part of something the access parameter
designates.  My hope is that there is a relatively simple
rule that eliminates any possibility of dangling pointers,
is relatively easy to check, and allows composability.

I'll try again, because it seems like my goals are reasonable,
but that the wording and the implementation model are not
yet clear enough.

****************************************************************

From: Tucker Taft
Sent: Tuesday, September 28, 2004  1:38 PM

Here is my earlier attempt to define the accessibility level of an
anonymous access type result:

   The accessibility level of the result is the
   maximum of the accessibility level of the function body,
   the accessibility level of any access parameters,
   and the accessibility level of any parameter with a
   tagged, aliased, or private part.

CHECK WHEN RETURNING AN OBJECT:

At the return statement, the implementation must check that the
above is true.  The simplest rule is that the accessibility
level of the designated object must not be as deep as that of
the function's outermost local variables.  It would be OK
to return a reference to a part of a formal parameter, so long as we "know"
the parameter was passed by reference.  Unfortunately pass-by-reference
is not really a property that is always known as part of the "logical"
interface to a type.  However, we can solve that by requiring that when
passing parameters to such a function, all parameters with any tagged
or aliased parts, *including those hidden inside private types,*
must be passed by reference.  This ensures that if the called
function could legitimately take 'Access of such a part, then
it will be referring to the actual, not a copy of it.

(Or we could just make objects with aliased parts always pass-by-reference,
though I think we had some reason to not require that.)

CHECK WHEN RETURNING ANOTHER FUNCTION CALL:

So the above seems to solve the problem of the check at the return
statement, when returning something other than a call on another
such function.

If we return a call on another such function, we basically have to
check that each parameter passed in which is an access parameter,
or has a tagged, aliased, or private part, has an appropriate
(i.e. non-local) accessibility level.  So this is not any
different from the check that would be required if we
directly returned 'Access applied to any such parameter, plus
a check that the called function is not itself nested in the calling
function.

ACCESSIBILITY LEVEL AT THE POINT OF CALL:

Next issue is what if we want to convert the result of such
a call to a named access type, or pass it in as an access parameter
to some other function.  In this case we need to come up with
a specific accessibility level.  For a conversion, we know
already the "deepest" it could be, so we might be able to
eliminate the check if the target access type has an accessibility
level that is also that deep.  But in the general conversion case,
and certainly for an access parameter, we will need to come up with
a level.

Again we go back to looking at the actual parameters passed into the function.
If one or more of them has a dynamic accessibility level (because it
is related to an outer (formal) access parameter), then I don't see
any alternative than to dynamically compute the deepest of those levels.
Presumably that is a rare case.  That dynamically computed max depth
must be "max"ed against the statically computed max depth of the
called function and the other 'Access-able parameters.

If there is only one actual parameter that has a dynamic accessibility
level, then the above computation is very similar to that which
is already required when passing an enclosing access parameter
into another function.  See AARM 3.10.2(22.dd) and/or John's
nice paper on this topic with a title being approximately
"Accessibility rules OK!" (Ada Letters Jan/Feb 1995 XV-1, pp. 39-49).

CONCLUSION:

My conclusion is this is doable, it would eliminate the dangling
reference problem while allowing a much more flexible rule for
returning anonymous access types, but still not require any
accessibility level to be passed back.

The check required at the return statement seems pretty easy
and intuitive to define.  The accessibility of the result
of such a call is trickier, but also seems relatively intuitive
(i.e. just the max of the function body and the parameters conceivably
allowing 'Access).

The cost/benefit ratio seems pretty good, and we could immediately
reap some of those benefits by simplifying and improving the
interface to the containers.

More comments?

Should I produce a more "official" wording proposal?

****************************************************************

From: Randy Brukardt
Sent: Tuesday, September 28, 2004  2:49 PM

Tucker replied to my second message:

> I think you are probably forgetting that accessibility levels
> are defined to be the *dynamic* nesting levels.  We do have
> rules about being statically more or less nested, but when
> I say accessibility level, I mean the dynamic one.  Hopefully
> the actual checks can usually be defined in terms of static
> checks.

OK. I won't go into the awfulness of this mistake in terms of the standard;
it just is.

> I think it is quite important that one function with an anonymous
> return type can return the result of calling another such function.

Yes, I agree; the rules above allowed that as long as the function was not a
nested one. That's what you want, because you certainly don't want to be
examining actuals to figure out if a function call is oK.

> I'll see if I can elaborate on the suggested wording and provide
> an implementation model.  The basic rule, from a user's model,
> is that a function cannot return a reference to a local object.
> That seems relatively intuitive.  What I am looking for is a rule
> that does *not* require the called function to return an accessibility
> level, but still provides maximum flexibility.

Yes, I think what I outlined above does that. Maybe not quite "maximum", but
reasonably close.

> The caller needs to
> assume that the called function might return a pointer into any
> object passed in where 'Access is legal, or it might return an
> access parameter, or 'Access of a part of something the access parameter
> designates.  My hope is that there is a relatively simple
> rule that eliminates any possibility of dangling pointers,
> is relatively easy to check, and allows composability.

Yes, that's a good goal, and it is what I proposed above. Why don't you
think my proposal (either of them) works??

In any case, if you give such a function a non-infinite level, you've
eliminated any hope of fixing the dangling pointer problem. The problem is
not just dangling pointers at the point of the call (which is a non-issue
for the container library, of course) but also pointers that are held too
long and become dangling in the future.

The issue is that pointers into a container can only be used for very short
periods of time; the infinite accessibility has that effect, as it prohibits
holding onto them for longer than the scope of the call. But any
non-infinite accessibility really doesn't do that. After all, Update_Element
is going to be library-level in many instantiations, there are no access
parameters or aliased parts, and the container will be allocated out of the
global heap -- so the resulting accessibility would be global. That's
*exactly* what we don't want!

So, if we're going to expend effort on this, we need to do it to meet this
goal. Or we have to understand why the simple rule that we currently have is
too restrictive. (After all, the simply rule works fine for the containers,
it just allows the access to live too long.)

****************************************************************

From: Tucker Taft
Sent: Tuesday, September 28, 2004  4:36 PM

>>>I would be tempted to split the
 >>>accessibility levels; it would be the level
>>>of the function for the return statement
 >>>(which would disallow local
>>>objects) and it would be infinite to the caller,
 >>>unless that caller was a
>>>return statement for a function that
 >>>returns anon access. In that case, the
>>>level used would be the level of the function
 >>>(which would disallow nested
>>>anon returns, but allow more global ones).

Just above you say the "level of the function" but we have two
functions at this point (the caller and the callee).  I
presume you are talking about the caller.  Presuming that
is right, "the level of the function" is somewhat
ambiguous.  Do you mean the level of the function declaration,
or the level of the local variables of the function?
I think we want it to be essentially the level of the
(by-reference) formal parameters, presuming we treat
that as a separate level from the locals, or equivalently,
the (dynamic) level of the call.  I also think you need to
address what happens when you pass the result of such a call
as an access parameter to another function.  We want these
to compose in a reasonable fashion, if you have a vector
of vectors.

>>I think it is quite important that one function with an anonymous
>>return type can return the result of calling another such function.
>
> Yes, I agree; the rules above allowed that as long as the function was not a
> nested one. That's what you want, because you certainly don't want to be
> examining actuals to figure out if a function call is oK.

I'm not sure exactly what you mean by that.  I am suggesting
you do need to examine the actuals to determine what is the
accessibility level of the result of the function call.
Otherwise what happens if you pass in a local vector and
then return a call on Element_Ptr (or whatever the anon-access-returning
function is called).  That should not be allowed.

>>I'll see if I can elaborate on the suggested wording and provide
>>an implementation model.  The basic rule, from a user's model,
>>is that a function cannot return a reference to a local object.
>>That seems relatively intuitive.  What I am looking for is a rule
>>that does *not* require the called function to return an accessibility
>>level, but still provides maximum flexibility.
>
> Yes, I think what I outlined above does that. Maybe not quite "maximum", but
> reasonably close.

I don't see how your rule on returning the result of
another function call is safe.

>>The caller needs to
>>assume that the called function might return a pointer into any
>>object passed in where 'Access is legal, or it might return an
>>access parameter, or 'Access of a part of something the access parameter
>>designates.  My hope is that there is a relatively simple
>>rule that eliminates any possibility of dangling pointers,
>>is relatively easy to check, and allows composability.
>
> Yes, that's a good goal, and it is what I proposed above. Why don't you
> think my proposal (either of them) works??

See above.

> In any case, if you give such a function a non-infinite level, you've
> eliminated any hope of fixing the dangling pointer problem. The problem is
> not just dangling pointers at the point of the call (which is a non-issue
> for the container library, of course) but also pointers that are held too
> long and become dangling in the future.

I don't believe this is a problem, because either the vector
is a local object or a global object.  Internally it might use
pointers, but the caller of Element_Ptr doesn't know that.
They have to assume the elements of the vector live directly
in the vector object, and so cannot return the result of calling
Element_Ptr(local-vector) to the "outside" world.

> The issue is that pointers into a container can only be used for very short
> periods of time; the infinite accessibility has that effect, as it prohibits
> holding onto them for longer than the scope of the call. But any
> non-infinite accessibility really doesn't do that. After all, Update_Element
> is going to be library-level in many instantiations, there are no access
> parameters or aliased parts, and the container will be allocated out of the
> global heap -- so the resulting accessibility would be global. That's
> *exactly* what we don't want!

I don't understand this.  The accessibility level is determined by
the actual parameters as well.  So if you pass in a local vector, you
can't return the result out of your local scope.  If you pass in
a global vector, then you can return the result.  That seems exactly
right.  We don't need to know that a global heap is being used
to implement the vector.  That's hidden in some private part.
We have to assume the worst at the point of calling Element_Ptr,
so I believe it is safe.

****************************************************************

From: Randy Brukardt
Sent: Tuesday, September 28, 2004  5:18 PM

> Just above you say the "level of the function" but we have two
> functions at this point (the caller and the callee).

I meant the level of the called function. The level of the return statement
(which is that of the function containing the return statement) doesn't
change - it's always the same. The level of the called function would
normally be infinite; but here I'm suggesting an exception to give it a
finite level so it can be returned again.

> I presume you are talking about the caller.

No, the called function.

> Presuming that
> is right, "the level of the function" is somewhat
> ambiguous.  Do you mean the level of the function declaration,
> or the level of the local variables of the function?
> I think we want it to be essentially the level of the
> (by-reference) formal parameters, presuming we treat
> that as a separate level from the locals, or equivalently,
> the (dynamic) level of the call. I also think you need to
> address what happens when you pass the result of such a call
> as an access parameter to another function.  We want these
> to compose in a reasonable fashion, if you have a vector
> of vectors.

It would have an infinite level, of course, and that couldn't be returned
again. It doesn't matter for the containers, because they don't have any
access parameters. (Indeed, no good Ada abstraction should have visible
access parameters - "in out" works the same.)

I also had proposed a different model which would allow that, but I don't
think it is as well defined.

> I'm not sure exactly what you mean by that.  I am suggesting
> you do need to examine the actuals to determine what is the
> accessibility level of the result of the function call.
> Otherwise what happens if you pass in a local vector and
> then return a call on Element_Ptr (or whatever the anon-access-returning
> function is called).  That should not be allowed.

No, that's perfectly OK, because you can't hold onto the pointer for longer
than the current block -- and that necessarily has to be shorter than the
local object's lifetime.

> > Yes, I think what I outlined above does that. Maybe not quite "maximum",
> > but reasonably close.
>
> I don't see how your rule on returning the result of
> another function call is safe.

I might have it wrong somewhere, but it certainly seems OK. The lifetime of
anything passed into the function necessarily is longer than that of the
function call (and thus the returned access). That's true of (outer)
functions as well. So as long as you can't return anything local (and the
prohibition on nested anon access functions and local objects should do
that), you should be OK.

> >>The caller needs to
> >>assume that the called function might return a pointer into any
> >>object passed in where 'Access is legal, or it might return an
> >>access parameter, or 'Access of a part of something the access parameter
> >>designates.  My hope is that there is a relatively simple
> >>rule that eliminates any possibility of dangling pointers,
> >>is relatively easy to check, and allows composability.
> >
> > Yes, that's a good goal, and it is what I proposed above. Why don't you
> > think my proposal (either of them) works??
>
> See above.

I'm afraid that your analysis was based on a flawed assumption, so I still
don't know why it would be unsafe. It's more restrictive than your proposal,
but your's doesn't work (see below).

> I don't believe this is a problem, because either the vector
> is a local object or a global object.  Internally it might use
> pointers, but the caller of Element_Ptr doesn't know that.
> They have to assume the elements of the vector live directly
> in the vector object, and so cannot return the result of calling
> Element_Ptr(local-vector) to the "outside" world.

No, that's not at all the issue. The problem is that future modifications to
the container (wherever it is stored) can "grow" the container and possibly
invalidate any accesses returned.

We'll have to say something about the returned access being erroneous if the
container is modified. I think we can "sell" that to the safety-first people
by pointing it is already true, even for the "process" subprogram version
(if you delete the object or do certain insertions, the cursor becomes
invalid). That simply can't be avoided.

But if the access can live longer than the call, then there is no hope of
containing the damage. That's a much harder sell than the current rules,
which essentially say that if your Process routine shoots yourself in the
foot, it hurts. :-)

I thought (and I think Bob thought) that you were trying to fix this
problem. Infinite accessibility does that; some finite level cannot.

> > The issue is that pointers into a container can only be used for very short
> > periods of time; the infinite accessibility has that effect, as it prohibits
> > holding onto them for longer than the scope of the call. But any
> > non-infinite accessibility really doesn't do that. After all, Update_Element
> > is going to be library-level in many instantiations, there are no access
> > parameters or aliased parts, and the container will be allocated out of the
> > global heap -- so the resulting accessibility would be global. That's
> > *exactly* what we don't want!
>
> I don't understand this.  The accessibility level is determined by
> the actual parameters as well.  So if you pass in a local vector, you
> can't return the result out of your local scope.  If you pass in
> a global vector, then you can return the result.  That seems exactly
> right.  We don't need to know that a global heap is being used
> to implement the vector.  That's hidden in some private part.
> We have to assume the worst at the point of calling Element_Ptr,
> so I believe it is safe.

Absolutely not. That would mean that you could hold onto accesses to global
objects forever, but they could become dangling very quickly (depending on
what operations are called afterwards). That is *precisely* the problem that
we're trying to solve. I've often had cases where I wanted to give an access
back that could only be used, not saved -- and this appears to be a solution
to that problem. If it doesn't solve that problem, then I don't care -- I'd
rather a simple solution (like the original proposal).

****************************************************************

From: Tucker Taft
Sent: Wednesday, September 29, 2004  12:02 AM

Unfortunately, without concrete examples, these kinds
of discussions almost invariably lead to misunderstandings.
So here is a concrete example:

    generic
        type Elem_Type is private;
        type Index_Type is range <>;
        Default: in Elem_Type;
    package Vectors is
        -- Define a growable vector type
        type Vector is private;

        function Empty_Vec return Vector; -- zero-length vector

        function Make_Vec(First : Index_Type;
          Last : Index_Type'Base) return Vector;
             -- Make vector with bounds First .. Last,
             -- all elements initialized to "Default"

        function Element_Ptr(
           V : access Vector; I : Index_Type)
          return not null access Elem_Type;
              -- Return (writable) reference to specified element
              -- Raise constraint_error if I is out of range

    private

        -- Possible implementation where first few elements of
        -- vector are directly in record, remaining on the heap

        type Elem_Array is
          array(Positive range <>) of aliased Elem_Type;

        type Vector is record
           First : Index_Type := Index_Type'First;
           Last : Index_Type'Base := Index_Type'First-1;
           First_Few : Elem_Array(1..4) := (others => Default);
           Remainder : access Elem_Array := null;
        end record;

    end Vectors;

        ...
    end Vectors;

    with Vectors;

    package Test_Ints is
        package Int_Vectors is new Vectors(Integer, Positive, 0);
        type Int_Vector is new Int_Vectors.Vector;  -- vector of ints

        package Int_Matrices is new Vectors(Int_Vector, Positive, Empty_Vec);
        type Int_Matrix is new Int_Matrices.Vector;
            -- vector of vector of ints, i.e. matrix of ints

        function Make_Matrix(Num_Rows, Num_Cols : Natural)
          return Int_Matrix;
             -- build matrix with given number of rows/columns
             -- initialized to all zeroes

        function Mtx_Elem_Ptr(M : access Int_Matrix; R, C : Positive)
          return not null access Integer;


        procedure Test_Stuff;

    end Test_Ints;

    package body Test_Ints is

        function Make_Matrix(Num_Rows, Num_Cols : Natural)
          return Int_Matrix is
            -- Build int matrix with given number of rows and columns
            Result : aliased Int_Matrix := Make_Vector(1, Num_Rows);
            Typical_Row : constant Int_Vector := Make_Vector(1, Num_Cols);
        begin
            -- Initialize each element of result with typical row
            for I in 1..Num_Rows loop
                Element_Ptr(Result'Access, I).all := Typical_Row;
            end loop;
        end Make_Matrix;

        function Mtx_Elem_Ptr(M : access Int_Matrix; R, C : Positive) return
          not null access Integer is
            -- Return ref to specified element of matrix
        begin
            return Element_Ptr(Element_Ptr(M, R), C);
               -- This is safe, and should be allowed
        end Mtx_Elem_Ptr;

        procedure Test_Stuff is
          -- declare some local objects and fiddle with them
            L : aliased Int_Vector := Make_Vector(First => 1, Last => 5);
            M : aliased Int_Matrix :=
              Make_Matrix(Num_Rows => 3, Num_Cols => 5);
        begin
            Mtx_Elem_Ptr(M'Access, 2, 4).all := 42; -- init M[2,4]
            Element_Ptr(L'Access, 3).all := 99; -- init L[3]
            Element_Ptr(M'Access, 1).all := L;  -- init M[1, *]
        end Test_Stuff;

        -- Prefix notation would help in the above, to eliminate
        -- need for 'Access.  Implicit deref of anon-result
        -- would eliminate need for ".all" (but I realize not
        -- much sympathy for that).

    end Test_Ints;

I think Randy and I were worried about two different kinds
of dangling references.  I was worried about the one that
would occur if you left the scope where a vector object was
declared.  Randy was worrying about dangling references
that would occur if you altered the vector object, with the
side effect of some part of it being deallocated and
then reallocated elsewhere.

This latter problem could happen with the access-procedure
approach as well, and I believe it is not possible to create
a reference that is so short-lived that you can completely
eliminate that problem.  Nevertheless, clearly if you make
the accessibility sufficiently "deep," the user won't be
able to convert it into a very long-lived named access type
nor store it in a very long-lived access object.

The first problem, namely allowing a reference to a part
of a local object to be returned, is clearly bad news,
and any proposal should prevent that.

I can sympathize with the desire to keep the accessibility
as "deep" as possible to minimize the chance of the latter
problem, but I think the kind of composability illustrated
in the above example is important, so any proposed rule
should be checked against such an example.

Randy, do you believe your proposed rule would prevent the
first kind of dangling reference, and still allow the
composability of the above example?

****************************************************************

From: Jean-Pierre Rosen
Sent: Wednesday, September 29, 2004  1:25 AM

> I'll try again, because it seems like my goals are reasonable,
> but that the wording and the implementation model are not
> yet clear enough.
>

Just as an input, if you can find wording that outlaws the following, I
think you are close to the solution:

function F (X : access T) return access T is
begin
    return X;
end F;

function G return access T is
    Local_Obj : T;
begin
    return F (Local_Obj);
end G;

****************************************************************

From: Pascal Leroy
Sent: Wednesday, September 29, 2004  4:11 AM

> I think Randy and I were worried about two different kinds of
> dangling references.  I was worried about the one that would
> occur if you left the scope where a vector object was
> declared.  Randy was worrying about dangling references that
> would occur if you altered the vector object, with the side
> effect of some part of it being deallocated and then
> reallocated elsewhere.

Thanks for the example and the clarification.  I have been watching this
thread with total bewilderment because I had no idea what problem you were
trying to solve.

My feeling is that the restrictions that you have to impose on the
function, in particular in the case where it returns a call to another
function, are so drastic as to seriously cripple
functions-returning-anonymous-accesses.

> This latter problem could happen with the access-procedure
> approach as well, and I believe it is not possible to create
> a reference that is so short-lived that you can completely
> eliminate that problem.

Well, to be honest, in the access-to-procedure approach, you could at
least "lock" the container while you are calling the access-to-procedure,
thereby detecting the situation where deallocation/reallocation would
happen.  I am not saying that we should require that, but it would be a
viable implementation option for situations where safety is a prime
concern.  On the other hand, if you return an access to a part of the
container, there is no way that you can prevent erroneousness.

****************************************************************

From: Cyrille Comar
Sent: Wednesday, September 29, 2004  10:09 AM

 > What if we make the accessibility
 > level for anonymous access return types "infinite"
 > depth, in the same way we do for anonymous
 > access-to-subp parameter types?  This would mean
 > that you pretty much have to use the result
 > immediately, or rename it, but you can't store
 > it away in a global without an Unchecked_Access.

That looks very attractive indeed and it looks like it would solve the
dangling reference issue nicely. I'd love to have the cake and eat it
too ;-)

Could you elaborate a little bit more to make sure that we get your
idea right?

****************************************************************

From: Tucker Taft
Sent: Thursday, September 30, 2004  3:30 PM

Here is another attempt to define the accessibility level of
an anonymous access type result, this time with "real" RM wording.

Change 3.10.2(7) as follows:

  Replace the sentence:
    A parameter of a master has the same accessibility level as
    the master.
  With:
    For a master that is a callable entity, a separate level is
    defined for any formal parameters; this *formal parameter level*
    is deeper than the innermost dynamically enclosing master,
    and the level of the master is in turn deeper than its formal
    parameter level.

Then we can define the accessibility level of the result of
calling a function returning an object of an anonymous type as follows:

    For a call on a function with a result of an anonymous access type,
    the accessibility level of the anonymous access type of the result
    is defined as the deepest of the following:

        - The accessibility level of the called function;
        - The accessibility level of any actual parameter with
          an aliased, tagged, or private part;
        - The accessibility level of the designated object for any
	 actual parameter corresponding to a formal access parameter.

    For the purposes of this definition, if any of the above levels are
    determined by the level of the anonymous access type of an access
    parameter of an enclosing subprogram S, that level is considered to
    be the same as the formal parameter level of S.

  AARM Note: This is an assume-the-worst rule for access parameters,
    to eliminate the need to take a "max" involving dynamic accessibility
    levels.

Add at an appropriate place in 6.5:

    At a return statement for a function with an anonymous result type:

      The accessibility level of the object designated by the
      returned value shall not be statically deeper than that
      of the formal parameter level of the enclosing function.

The above rules eliminate the "dynamicness" from the earlier
attempt, by assuming the "worst" about objects designated by access
parameters.

It ensures you don't return pointers into local variables,
but allows returning pointers into formal parameters
or objects designated by access parameters.  The caller
knows enough about the actual parameters to guarantee that the
returned pointer is not used outside the scope of what
it designates.

-----------------------------------------------------------

Here is my initial attempt, for historical reference:

    The accessibility level of the result is the
    maximum of the accessibility level of the function body,
    the accessibility level of any access parameters,
    and the accessibility level of any parameter with a
    tagged, aliased, or private part.

I hadn't formalized the rule for the check upon function return.
To do that right, it seems necessary to define a distinct
"formal parameter level" as I have done above.

****************************************************************

From: Robert Dewar
Sent: Friday, October  1, 2004  8:11 AM

> Sorry, folks, but we have to draw the line at some point.

I disagree, it is far more important for things to be right, than to be
rushed in with inadequate review. Just because there is a perceived deadline
is no reason to cut off discussion in my view. I think it is premature
to give up on the idea of infinite accessibility depth. It is never too
late for a change that needs to be made.

Nothing about Ada 2005 (or 2006 or whatever it turns out to be) is
urgent. Yes, it is important, but really not urgent, and what is important
is to get things right.

I think this rush which I perceive going on in a number of areas has
a real risk of creating something less than what we want for the new
version of Ada.

Yes, we have customers eager to get the new Ada features, and indeed
many of them are using these features already. It actually would be
just fine if the formal approval were not rushed so much, to give
users a chance to look at what the ARG has been up to, and implementors
a chance to implement the new features.

****************************************************************

From: Tucker Taft
Sent: Friday, October  1, 2004  11:40 AM

> 4 - Give up on the idea of infinite accessibility depth for function
> results.  It's just too late for such a change.  We don't have the time
> necessary to work out the implications of that change.  In particular,
> the assume-the-worst rules for access parameters could significantly
> reduce the usefulness of functions returning an anonymous access type.
> AI 318 has been quite contentious in the past; don't rock the boat.

I am less certain of this.  If we put in an anon access return
now using the simplistic semantics, we pretty much rule out
ever going with the more "advanced" semantics.  On the other
hand, if we put in something like what I suggested, we can
go to a more dynamic check on access parameters, for example,
in the future if that turns out to be important.

The "simplistic" semantics of anon-access-return is no different
from declaring a named access type.  That means it really isn't
providing much of any new power, though it does help avoid the
access type proliferation problem.  The "advanced" semantics
would give us something we don't have now, an ability to safely
return a reference to a component of a data structure.

As far as the specific issue of access parameters, note that
the limitation assumes the worst at the point of the check,
but doesn't propagate that assumption back to a point where
you know what the access parameter designates.  For example:

     function Part_Of(Ptr : access T) return access Elem;

     function Subpart_of(Ptr : access Elem) return access Subpart;

     ...

     Global : aliased T;

     ...

     ... Subpart_Of(Part_Of(Global'Access)).all  -- this has lib-level
                                             -- accessibility

This call on Subpart_Of has lib-level accessibility, even though
the check at the return statements inside Part_Of and Subpart_Of
both have to assume the worst about their access parameter.

>
> I am going to ask Randy to update AI 302 according to 1, 2, and 3 above.
> Also, AI 318 was approved with changes at the last meeting, so I am
> going to send it to WG9 in November (after editorial review), unless
> someone asks for a letter ballot.
>
> Sorry, folks, but we have to draw the line at some point.

I agree with that.  I just don't want that line to rule out
future possibilities, if we can avoid it.

****************************************************************

From: Robert A. Duff
Sent: Friday, October  1, 2004  12:06 PM

> 4 - Give up on the idea of infinite accessibility depth for function
> results.  It's just too late for such a change.  We don't have the time
> necessary to work out the implications of that change.  In particular,
> the assume-the-worst rules for access parameters could significantly
> reduce the usefulness of functions returning an anonymous access type.
> AI 318 has been quite contentious in the past; don't rock the boat.

I don't agree.  This is one case where C++ wins.  In Ada, you have a
choice: unreadable code, or unsafe code.  Furthermore, once we've
decided what the accessibility level of those things is, it will be much
harder to change our mind.

Note that if you want the other accessibility rules, you can use a named
access type.

> I am going to ask Randy to update AI 302 according to 1, 2, and 3 above.
> Also, AI 318 was approved with changes at the last meeting, so I am
> going to send it to WG9 in November (after editorial review), unless
> someone asks for a letter ballot.

If I ask for a letter ballot, does that mean we can discuss (and perhaps
approve) Tucker's latest proposal for accessibility rules?  (By the way,
it's not "infinite" as you said above.)

> Sorry, folks, but we have to draw the line at some point.

True.

****************************************************************

From: Randy Brukardt
Sent: Friday, October  1, 2004  3:07 PM

> If I ask for a letter ballot, does that mean we can discuss (and perhaps
> approve) Tucker's latest proposal for accessibility rules?  (By the way,
> it's not "infinite" as you said above.)

The only way to "approve" a different set of accessibility rules would be to
reopen the AI, or create another AI. A Letter Ballot could reopen the AI,
but of course that would completely reopen the AI. And at this point, there
is as much chance that we'd completely drop the AI as continue.

So my suggestion would be to create a new AI covering the accessibility
rules. I think it would be included under the WG9 scope, as it should be
considered an "improvement".

But I think it is wasted effort, complicating something that exists more for
completeness than utility. Moreover, it doesn't actually help: what you want
to do as the writer of a library is to have control over the lifetime of
access types either to improve safety or to control resource usage (the
problem in Claw). None of these proposals really give the library writer any
control -- they presume that the client doesn't abuse the feature. But
that's not an acceptable way to design something; you have to protect
against abuse as you can't trust the client to do the right thing (even if
they intended to do so).

So in my view, Tucker is trying to solve a problem which isn't particularly
a problem. It would help in a few rare cases, but in general it would do
nothing other than increase the confusion on the meaning of the rules.

****************************************************************

From: Randy Brukardt
Sent: Friday, October  1, 2004  3:19 PM

I neglected to mention that reopening the AI means that I will have to
exclude it from the draft RM/AARM that I'm working on. That means that it
won't be reviewed as well as AIs that are included this year - review of the
changes in place in the text of the Standard finds many problems that slip
by in the AI format.

****************************************************************

From: Randy Brukardt
Sent: Friday, October  1, 2004  6:34 PM

> I am less certain of this.  If we put in an anon access return
> now using the simplistic semantics, we pretty much rule out
> ever going with the more "advanced" semantics.

I don't see this. Any rule has to allow returning of things more global than
the function. So any enhancement to the rule is simply going to allow
returning of more things. Similarly, on the calling side, a new rule is
going to allow returning of things with a shorter lifetime -- but that will
not prevent existing calls (which return longer-lived things from working).

I'm presuming that the infinite accessibility idea is dead, because it would
make what you could do with an anonymous access function fairly limited. I
know that none of the proposals that you have currently have such a short
lifetime. (I don't think that Bob understands this.)

>  On the other
> hand, if we put in something like what I suggested, we can
> go to a more dynamic check on access parameters, for example,
> in the future if that turns out to be important.

True, but I think that's true of your current proposal as well. Indeed, I
think (in the absence of a real infinite accessibility proposal), any
proposal would have to meet that goal, simply to avoid surprises.

> The "simplistic" semantics of anon-access-return is no different
> from declaring a named access type.  That means it really isn't
> providing much of any new power, though it does help avoid the
> access type proliferation problem.  The "advanced" semantics
> would give us something we don't have now, an ability to safely
> return a reference to a component of a data structure.

Only if the data structure doesn't have an indirect components or those
components can't be modified out of existence. That's a pretty rare case in
practice (it certainly isn't true for any of the containers). Otherwise, it
only provides an illusion of safety.

Anyway, as I told Bob, I think this idea can be explored in a separate AI.
That's certainly true if we are following your proposed rule, which is
certainly compatible with the simple semantics. (And better be.)

****************************************************************

From: Tucker Taft
Sent: Friday, October  1, 2004  9:11 PM

>>I am less certain of this.  If we put in an anon access return
>>now using the simplistic semantics, we pretty much rule out
>>ever going with the more "advanced" semantics.
>
> I don't see this. Any rule has to allow returning of things more global than
> the function. So any enhancement to the rule is simply going to allow
> returning of more things. Similarly, on the calling side, a new rule is
> going to allow returning of things with a shorter lifetime -- but that will
> not prevent existing calls (which return longer-lived things from working.

Here is my concern:
If we go with the originally proposed semantics, then at the
call site, the result has the accessibility level of the
function declaration, independent of whether you pass in
a local object.  With this new ("advanced") proposal,
the accessibility level of the result of the call could be
deeper.  Adopting these "advanced" semantics in Ada 2015
(should we live so long ;-) would break any Ada 2005 code which
had taken  advantage of it being at the same level as the
function declaration, by for example, converting the result
to a named access type. Hence we should be sure we have
the "right" answer here, for posterity's sake.

In any case, I think your suggestion of making this a new AI makes sense,
so that we leave 318 as is, but then (perhaps) consider a new
AI which modifies the result of 318.  If the new AI is rejected,
then 318 stands.  If I continue to feel excited by this sufficiently,
I'll write up the new AI.  Pascal can then decide whether it
is worth considering in Atlanta...

****************************************************************

From: Pascal Leroy
Sent: Saturday, October  2, 2004  3:33 AM

Robert wrote:

> Nothing about Ada 2005 (or 2006 or whatever it turns out to
> be) is urgent. Yes, it is important, but really not urgent,
> and what is important is to get things right.
>
> I think this rush which I perceive going on in a number of
> areas has a real risk of creating something less than what we
> want for the new version of Ada.

I have a mandate from WG9 to create an Amendment document in the 2005
timeframe, and the schedule is well-defined and has been established years
ago.  When I took this job (that of ARG Chair) I committed to doing my
best to implement the WG9 decisions.

You have expressed several times your discomfort with the schedule.
Grumbling on the ARG list is not going to cause anything to change.  If
you want the schedule modified, you should work through your national body
representative to bring up the issue at the next WG9 meeting, to be held
in Atlanta on November 18th.

At the Palma WG9 meeting in June, WG9 agreed on a scope document for the
Amendment.  So to some extent the contents of the Amendment are defined
now.  I have been flexible in accommodating new ideas, but I cannot let
half-baked proposals sneak in at the last minute.  There is a point where
the best is the enemy of the good.

From now on I am going to ask that significant disagreements be resolved
by letter ballots.  This is the only way that we can come to clear-cut
decisions in the required timeframe.  Furthermore, I want ARG members to
face their responsibilities: calling for a letter ballot is not something
that should be done light-heartedly, as there is some probability that it
could just kill the AI.

Of course, you are an ARG member, so you can call for a letter ballot on
any AI at any time.  But the schedule is cast in concrete as far as I am
concerned.

PS: I should add that if WG9 decided to slip the schedule by one or two
years, my company would probably lose interest in the whole process, and
curtail or withdraw its support.

PPS: History has demonstrated that there are drawbacks to having a
stubborn Frenchman organize this effort.

****************************************************************

From: Pascal Leroy
Sent: Saturday, October  2, 2004  3:46 AM

> Note that if you want the other accessibility rules, you can
> use a named access type.

That's bogus and you know it.  As part of this Amendment, we are trying
very hard to avoid the proliferation of access types.  This is the
justification for several AIs, including 318.  Now if you tell me that in
this case I have to use named access types to circumvent pessimistic
accessibility rules, then functions returning anonymous access types are
just not worth it in my opinion.

> If I ask for a letter ballot, does that mean we can discuss
> (and perhaps approve) Tucker's latest proposal for accessibility rules?

The letter ballot would be on AI 318, which was approved at the last
meeting.  If this AI is approved by the letter ballot, it goes to WG9 as
is.  If it is rejected, it goes back to the ARG and will be discussed in
Atlanta.  Given the schedule constraints, this is likely to cause it to be
dropped unless we can come up with a complete agreement during the Atlanta
meeting (this has happened in the past, but only for simple AIs).

****************************************************************

From: Pascal Leroy
Sent: Saturday, October  2, 2004  4:03 AM

> Hence we should be sure we
> have the "right" answer here, for posterity's sake.

Agreed.  Note that it goes both ways: if we can prevent dangling
references, that's a good thing to do; on the other hand, we should make
sure that functions returning anonymous access types are useful/usable.
We do want a fiasco like that of limited types.

> In any case, I think your suggestion of making this a new AI
> makes sense, so that we leave 318 as is, but then (perhaps)
> consider a new AI which modifies the result of 318.  If the
> new AI is rejected, then 318 stands.  If I continue to feel
> excited by this sufficiently, I'll write up the new AI.
> Pascal can then decide whether it is worth considering in Atlanta...

If you write an AI, I'll be happy to discuss it in Atlanta.  However,
remember that AIs that are not "approved with changes" in Atlanta are
unlikely to make it into the Amendment.  So you should have a fully worked
out AI, complete with an analysis of the consequences of the rules.  If
the group likes it, it should be able to go forward with only minor
changes (you generally get your wording right).  If the group doesn't like
it, too bad.

****************************************************************

From: Robert Dewar
Sent: Saturday, October  2, 2004  5:21 AM

Pascal Leroy wrote:

> You have expressed several times your discomfort with the schedule.
> Grumbling on the ARG list is not going to cause anything to change.  If
> you want the schedule modified, you should work through your national body
> representative to bring up the issue at the next WG9 meeting, to be held
> in Atlanta on November 18th.

It is not the schedule per se that makes me uncomfortable, it is using
the schedule to cut off debate, with the result of possibly arriving
at a language proposal that is less than ideal.

> At the Palma WG9 meeting in June, WG9 agreed on a scope document for the
> Amendment.  So to some extent the contents of the Amendment are defined
> now.  I have been flexible in accommodating new ideas, but I cannot let
> half-baked proposals sneak in at the last minute.  There is a point where
> the best is the enemy of the good.

Yes, that's fair as a general principle, but it is also the case that the
sky does not fall if a particular proposal does not make it into the
standard. I am comfortable with:

   "Hey, guys, if this feature is going to make it into the standard,
    we have to make a decision soon here. It's up to you, but we can't
    sit around and discuss this for ever."

I am not so comfortable with

   "SOrry, this feature has to be done by xxx date, therefore we will
    make an arbitrary decision in order to meet this deadline."

> From now on I am going to ask that significant disagreements be resolved
> by letter ballots.  This is the only way that we can come to clear-cut
> decisions in the required timeframe.

That seems quite reasonable, with the understanding that you really
want to try to avoid a situation where something important happens
by a 3-2 with 5 abstentions vote :-)

> Furthermore, I want ARG members to
> face their responsibilities: calling for a letter ballot is not something
> that should be done light-heartedly, as there is some probability that it
> could just kill the AI.

Indeed, but that's not the end of the world, if something doesn't make
it into the standard because it is not ready, that's an acceptable
outcome to me. And if calling for a letter ballot causes an AI to
be killed, I would say it deserves to die.

Rushing things into a standard prematurely is not letting good be
the enemy of best, it is more like contaminating what would otherwise
be good with something that is not up to the standard.

That being said, there probably are cases where a letter ballot will
close off debate and show that in fact people are collectively quite
happy with the good, and are willing to put off the best :-)

> Of course, you are an ARG member, so you can call for a letter ballot on
> any AI at any time.  But the schedule is cast in concrete as far as I am
> concerned.

OK, but if the schedule is cast in contract, the set of features to
go into the revision is not! Even with the much greater resources
available for the 9X upgrade, we still ended up rushing some things
in, and they cause continual trouble (the radical change in Size
semantics between most Ada 83 compilers and the Ada 95 standard
is, I would say, the source of about half the porting problems,
and really happened because we did not spend enough time on this.
I can particularly say that, since I feel I was one of the people
who should have found more time on this particular issue :-)

I guess what I reacted to was that you seemed a bit in the mode
of taking an executive decision to move the discussion in
a particular direction, using the time scale as a justification.
That makes me uneasy. I am not uneasy if you or anyone else
reminds us that continued debate on an issue may mean that we
have to postpone putting the feature into the language.

One further thought about Ada 2005. In fact this update is all
about moving from good to best. We can always achieve good by
doing nothing at all :-)

****************************************************************

From: Jean-Pierre Rosen
Sent: Saturday, October  2, 2004  3:09 PM

>>From now on I am going to ask that significant disagreements be resolved
> by letter ballots.  This is the only way that we can come to clear-cut
> decisions in the required timeframe.
For completeness:
if the ARG has two different proposals and cannot decide which one is
preferred, there is also the solution of asking for a letter ballot at
WG9 level.

****************************************************************

From: Pascal Leroy
Sent: Monday, October  4, 2004  2:29 AM

Robert noted:

> That seems quite reasonable, with the understanding that you
> really want to try to avoid a situation where something
> important happens by a 3-2 with 5 abstentions vote :-)

The procedures specify that, for an AI to be accepted, it has to garner
2/3 of the votes of the members who respond to the letter ballot.  Thus, a
3-2-5 vote would be deemed inconclusive, and the AI would be sent back to
the ARG (and probably killed, but you never know).

****************************************************************

From: Robert A. Duff
Sent: Tuesday, October  5, 2004  1:32 PM

> > Note that if you want the other accessibility rules, you can
> > use a named access type.
>
> That's bogus and you know it.

Sorry, but I don't find that argument compelling.  ;-)

>...  As part of this Amendment, we are trying
> very hard to avoid the proliferation of access types.

I thought proliferation of uninteresting type conversions was the more
important issue.

>...  This is the
> justification for several AIs, including 318.  Now if you tell me that in
> this case I have to use named access types to circumvent pessimistic
> accessibility rules, then functions returning anonymous access types are
> just not worth it in my opinion.

I think that attaching semantics to anonymity is a kludge (sorry, Tuck).
That is, "X: access T;" ought to mean precisely the same thing as
"X: T_Ptr;" for a suitable definition of T_Ptr.

However, we already violated that when access parameters were invented.
Those have special accessibility rules, so it's not *completely* bogus
to at least consider the idea that "return access T" should have special
accessibility rules.

On the one hand, I'd like to be able to get rid of pretty-much all named
access types; "by name" type equivalence is almost never of any use for
access types.  From that point of view, it makes sense to make the
accessibility rules for "return access T" identical to "return T_Ptr".

On the other hand, the lack of functions returning something like a C++
reference is a huge hole in the language.  So, no, I don't agree that
"That's bogus and [I] know it."  The truth is, I have mixed feelings.

In a perfect world, I could have the best of both.

It sure would be nice to have accessor functions that return references
that can't dangle.  If the price is a few extra type conversions,
well... why not?  I'll have to reread the AI's to be sure, but I think
the extra type conversions would be fairly rare in this case (function
returns).

> > If I ask for a letter ballot, does that mean we can discuss
> > (and perhaps
> > approve) Tucker's latest proposal for accessibility rules?
>
> The letter ballot would be on AI 318, which was approved at the last
> meeting.  If this AI is approved by the letter ballot, it goes to WG9 as
> is.  If it is rejected, it goes back to the ARG and will be discussed in
> Atlanta.  Given the schedule constraints, this is likely to cause it to be
> dropped unless we can come up with a complete agreement during the Atlanta
> meeting (this has happened in the past, but only for simple AIs).

OK.  I still think it's worth discussing, but as a separate AI.
If it doesn't make it, then so be it.

****************************************************************

From: Robert A. Duff
Sent: Tuesday, October  5, 2004  1:37 PM

> I'm presuming that the infinite accessibility idea is dead, because it would
> make what you could do with an anonymous access function fairly limited. I
> know that none of the proposals that you have currently have such a short
> lifetime. (I don't think that Bob understands this.)

Well, I can't seem to parse the sentence starting "I know...", so I'm
not sure what "this" is, so I've no idea whether I understand it.  ;-)
Could you please clarify what it is that I do not understand?

****************************************************************

From: Randy Brukardt
Sent: Tuesday, October  5, 2004  3:14 PM

Randy corrects himself:

> I'm presuming that the infinite accessibility idea is dead, because it would
> make what you could do with an anonymous access function fairly limited. I
> know that none of the proposals that Tucker currently is making have such
> a short lifetime for the return. (I don't think that Bob understands this.)

Hopefully Bob will now understand what it is that I think he doesn't
understand, although he may not really understand the full meaning and have
a deep understanding of the issues... :-)

****************************************************************


Questions? Ask the ACAA Technical Agent