comp.lang.ada
 help / color / mirror / Atom feed
* Overloading operator “=” for anonymous access types?
@ 2019-01-11 21:46 daicrkk
  2019-01-12  9:50 ` Simon Wright
  0 siblings, 1 reply; 17+ messages in thread
From: daicrkk @ 2019-01-11 21:46 UTC (permalink / raw)


I am working my way through Barnes' excellent Ada book. This is a code sample for deep comparison of linked lists from section 11.7:


type Cell is
  record
    Next: access Cell;
    Value: Integer;
  end record;

function "=" (L, R: access Cell) return Boolean is
begin
  if L = null or R = null then    -- universal =
    return L = R;                 -- universal = (Line A)
  elsif L.Value = R.Value then
    return L.Next = R.Next;       -- recurses OK (Line B)
  else
    return False;
  end if;
end "=";


I can't seem to wrap my head around why in Line A operator "=" of the universal_access type is called (because of the preference rule), on Line B, however, the user-defined operator "=" is called (which makes recursion possible in the first place), this time with no preference for operator "=" of universal_access.

Both L and R, as well as L.Next and R.Next are of the same anonymous type "access Cell". Why the difference in "dispatching"? Does it have to do with L and R being access parameters? If so, what is the rule there?

I did my best to find anything in the AARM, especially section 4.5.2, but could not make any sense of it.

Cheers.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Overloading operator “=” for anonymous access types?
  2019-01-11 21:46 Overloading operator “=” for anonymous access types? daicrkk
@ 2019-01-12  9:50 ` Simon Wright
  2019-01-12 14:01   ` Simon Wright
  2019-01-12 15:15   ` daicrkk
  0 siblings, 2 replies; 17+ messages in thread
From: Simon Wright @ 2019-01-12  9:50 UTC (permalink / raw)


daicrkk@googlemail.com writes:

> I am working my way through Barnes' excellent Ada book. This is a code
> sample for deep comparison of linked lists from section 11.7:
>
>
> type Cell is
>   record
>     Next: access Cell;
>     Value: Integer;
>   end record;
>
> function "=" (L, R: access Cell) return Boolean is
> begin
>   if L = null or R = null then    -- universal =
>     return L = R;                 -- universal = (Line A)
>   elsif L.Value = R.Value then
>     return L.Next = R.Next;       -- recurses OK (Line B)
>   else
>     return False;
>   end if;
> end "=";
[...]
> I did my best to find anything in the AARM, especially section 4.5.2,
> but could not make any sense of it.

Given ARM 4.5.2(9.1 ff),

   At least one of the operands of an equality operator for
   universal_access shall be of a specific anonymous access type. Unless
   the predefined equality operator is identified using an expanded name
   with prefix denoting the package Standard, neither operand shall be
   of an access-to-object type whose designated type is D or D'Class,
   where D has a user-defined primitive equality operator such that:

   * its result type is Boolean;

   * it is declared immediately within the same declaration list as D or
     any partial or incomplete view of D; and

   * at least one of its operands is an access parameter with designated
     type D.

I'm not at all clear why the example code is legal, or why it would be
legal to call it; since 'access Cell' appears to match "neither operand
shall be of an access-to-object type whose designated type is D or
D'Class, where D has a user-defined primitive equality operator ..."

Might explain why compiling this example with GNAT (CE 2018) results in
stack overflow.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Overloading operator “=” for anonymous access types?
  2019-01-12  9:50 ` Simon Wright
@ 2019-01-12 14:01   ` Simon Wright
  2019-01-12 15:15   ` daicrkk
  1 sibling, 0 replies; 17+ messages in thread
From: Simon Wright @ 2019-01-12 14:01 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> I'm not at all clear why the example code is legal, or why it would be
> legal to call it; since 'access Cell' appears to match "neither operand
> shall be of an access-to-object type whose designated type is D or
> D'Class, where D has a user-defined primitive equality operator ..."

Still not clear.

Note to self: do *not* attempt to define "=" for anonymous access types!

Would have liked the AIs to have said "it is illegal to define "=" for
anonymous access types".


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Overloading operator “=” for anonymous access types?
  2019-01-12  9:50 ` Simon Wright
  2019-01-12 14:01   ` Simon Wright
@ 2019-01-12 15:15   ` daicrkk
  2019-01-14 23:08     ` Overloading operator "=" " Randy Brukardt
  1 sibling, 1 reply; 17+ messages in thread
From: daicrkk @ 2019-01-12 15:15 UTC (permalink / raw)


On Saturday, January 12, 2019 at 10:50:17 AM UTC+1, Simon Wright wrote:
> daicrkk@googlemail.com writes:
> 
> > I am working my way through Barnes' excellent Ada book. This is a code
> > sample for deep comparison of linked lists from section 11.7:
> >
> >
> > type Cell is
> >   record
> >     Next: access Cell;
> >     Value: Integer;
> >   end record;
> >
> > function "=" (L, R: access Cell) return Boolean is
> > begin
> >   if L = null or R = null then    -- universal =
> >     return L = R;                 -- universal = (Line A)
> >   elsif L.Value = R.Value then
> >     return L.Next = R.Next;       -- recurses OK (Line B)
> >   else
> >     return False;
> >   end if;
> > end "=";
> [...]
> > I did my best to find anything in the AARM, especially section 4.5.2,
> > but could not make any sense of it.
> 
> Given ARM 4.5.2(9.1 ff),
> 
>    At least one of the operands of an equality operator for
>    universal_access shall be of a specific anonymous access type. Unless
>    the predefined equality operator is identified using an expanded name
>    with prefix denoting the package Standard, neither operand shall be
>    of an access-to-object type whose designated type is D or D'Class,
>    where D has a user-defined primitive equality operator such that:
> 
>    * its result type is Boolean;
> 
>    * it is declared immediately within the same declaration list as D or
>      any partial or incomplete view of D; and
> 
>    * at least one of its operands is an access parameter with designated
>      type D.
> 
> I'm not at all clear why the example code is legal, or why it would be
> legal to call it; since 'access Cell' appears to match "neither operand
> shall be of an access-to-object type whose designated type is D or
> D'Class, where D has a user-defined primitive equality operator ..."
> 
> Might explain why compiling this example with GNAT (CE 2018) results in
> stack overflow.

I second that. Access Cell is an access-to-object type whose designated type is Cell (check), Cell has a user-defined primitive equality operator (check) such that its result type is Boolean (check), it is declared immediately within the same declaration list as Cell (check), at least one of its operands is an access parameter with designated type Cell (both operands are, check).
According to 4.5.2, universal_access "=" should never be allowed to kick in at all here, not even with "L = null". Or am I missing something?

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Overloading operator "=" for anonymous access types?
  2019-01-12 15:15   ` daicrkk
@ 2019-01-14 23:08     ` Randy Brukardt
  2019-01-15  0:34       ` Shark8
                         ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Randy Brukardt @ 2019-01-14 23:08 UTC (permalink / raw)


<daicrkk@googlemail.com> wrote in message 
news:0c56d9f4-8861-4c74-b170-a973e3789b08@googlegroups.com...

>I second that. Access Cell is an access-to-object type whose designated
>type is Cell (check), Cell has a user-defined primitive equality operator
>(check) such that its result type is Boolean (check), it is declared
>immediately within the same declaration list as Cell (check), at least one
>of its operands is an access parameter with designated type Cell (both
>operands are, check).
>According to 4.5.2, universal_access "=" should never be allowed to kick in
>at all here, not even with "L = null". Or am I missing something?

Yup, I agree with this. My first thought when reading that example is that 
it is wrong, because I don't remember anywhere in Ada where the same 
operator with arguments of the same type means different things. I don't 
think the use of "null" could change that.

Dunno if John wrote that for a different version of Ada, or he was just 
confused by a rule that barely makes sense anyway.

As always, best avoid anonymous access types unless you have to use one of 
their special features (dynamic accessibility, dispatching, special 
discriminant accessibility, or closures [for access-to-subprograms]). And 
better still, lets lobby to get those special features optionally available 
for named access types so no one every has to use an anonymous anything. :-)

                                          Randy.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Overloading operator "=" for anonymous access types?
  2019-01-14 23:08     ` Overloading operator "=" " Randy Brukardt
@ 2019-01-15  0:34       ` Shark8
  2019-01-15  8:38       ` Dmitry A. Kazakov
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 17+ messages in thread
From: Shark8 @ 2019-01-15  0:34 UTC (permalink / raw)


On Monday, January 14, 2019 at 4:08:36 PM UTC-7, Randy Brukardt wrote:
> 
> As always, best avoid anonymous access types unless you have to use one of 
> their special features (dynamic accessibility, dispatching, special 
> discriminant accessibility, or closures [for access-to-subprograms]). And 
> better still, lets lobby to get those special features optionally available 
> for named access types so no one every has to use an anonymous anything. :-)

Well, I'm all for getting rid of anonymous access types altogether -- though that might not be acceptable to the rest of the ARG as it would make previously-valid Ada non-valid, I think reducing the complexity of the language (and reduce instances of "a rule that barely makes sense anyway").

I thought there was an AI for first class subprograms / subprogram types, but I couldn't find it with a quick search... so either I'm misremembering or I'm just hitting all the wrong keywords in the search.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Overloading operator "=" for anonymous access types?
  2019-01-14 23:08     ` Overloading operator "=" " Randy Brukardt
  2019-01-15  0:34       ` Shark8
@ 2019-01-15  8:38       ` Dmitry A. Kazakov
  2019-01-15 21:00         ` Randy Brukardt
  2019-01-15  8:51       ` daicrkk
  2019-01-17  3:20       ` Jere
  3 siblings, 1 reply; 17+ messages in thread
From: Dmitry A. Kazakov @ 2019-01-15  8:38 UTC (permalink / raw)


On 2019-01-15 00:08, Randy Brukardt wrote:
> <daicrkk@googlemail.com> wrote in message
> news:0c56d9f4-8861-4c74-b170-a973e3789b08@googlegroups.com...
> 
>> I second that. Access Cell is an access-to-object type whose designated
>> type is Cell (check), Cell has a user-defined primitive equality operator
>> (check) such that its result type is Boolean (check), it is declared
>> immediately within the same declaration list as Cell (check), at least one
>> of its operands is an access parameter with designated type Cell (both
>> operands are, check).
>> According to 4.5.2, universal_access "=" should never be allowed to kick in
>> at all here, not even with "L = null". Or am I missing something?
> 
> Yup, I agree with this. My first thought when reading that example is that
> it is wrong, because I don't remember anywhere in Ada where the same
> operator with arguments of the same type means different things. I don't
> think the use of "null" could change that.

But the types are not same. It is universal_access vs. access.

> Dunno if John wrote that for a different version of Ada, or he was just
> confused by a rule that barely makes sense anyway.
> 
> As always, best avoid anonymous access types unless you have to use one of
> their special features (dynamic accessibility, dispatching, special
> discriminant accessibility, or closures [for access-to-subprograms]). And
> better still, lets lobby to get those special features optionally available
> for named access types so no one every has to use an anonymous anything. :-)

Named or anonymous it makes little difference, IMO.

Here is a classic multi-method case. "=" is such an operation. null is 
universal_access (4.2). For any access type P there are 3 equality 
operations "=":

    function "=" (Left, Right : universal_access) return Boolean;

    type P is access T;
    function "=" (Left : P; Right : universal_access) return Boolean;
    function "=" (Left : universal_access; Right : P) return Boolean;
    function "=" (Left, Right : P) return Boolean;

When the last one is overridden, what happens with the second and the third?

One of three possibilities:

1. It inherits the base operation:

    function "=" (Left : P; Right : universal_access) return Boolean is
    begin
       return universal_access (Left) = Right;
    end "=";

2. It silently overrides:

    function "=" (Left : P; Right : universal_access) return Boolean is
    begin
       return Left = P (Right);
    end "=";

3. It gets overridden abstract and comparison to null becomes illegal 
because the operation is not defined.

[ The reference manual is shy to say anything about it. It claims that 
universal_access is kind of class-wide, which would mean, if taken 
seriously, that "=" overloads and must clash with the original "=". 
Since it does not, universal_access is more like a parent type than 
class-wide.]

It seems that in the OP's case as in the case with named access types #2 
is in effect, which is illogical, inconsistent, unsafe, but would be 
expected by most people.

Barnes' code presumes rather #1, which is logical, but confusing and 
error-prone.

#3 would be consistent and safe:

    if Ptr_Value = Ptr_Type (null) then -- Type conversion required

But it would not work with anonymous access types. So, if #3 were 
adopted, then overriding for anonymous types must be banished.

All this is fine and good, except that overriding

   function "=" (Left, Right : access T) return Boolean;

is also a primitive of T! You cannot banish it.

P.S. And, wouldn't it be better to fix the type system, no?

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Overloading operator "=" for anonymous access types?
  2019-01-14 23:08     ` Overloading operator "=" " Randy Brukardt
  2019-01-15  0:34       ` Shark8
  2019-01-15  8:38       ` Dmitry A. Kazakov
@ 2019-01-15  8:51       ` daicrkk
  2019-01-15 11:15         ` Simon Wright
  2019-01-17  3:20       ` Jere
  3 siblings, 1 reply; 17+ messages in thread
From: daicrkk @ 2019-01-15  8:51 UTC (permalink / raw)


Thx for the insight on anonymous access types being somewhat problematic. I have not yet gotten so far into learning the language as to see this myself.

For anyone interested I have tried to summarize my findings with regard to the example (as I did on SO). Please correct me if I'm wrong:

According to the standard, L = null, R = null, L = R as well as L.Next = R.Next should each unambiguously call the user-defined operator =. universal_access operator = must not kick in at all here.

Reason:

The operands L, R, L.Next and R.Next violate the precondition in ARM 4.5.2(9.1-9.4) for interpreting = in these expressions as to mean operator = of the unviversal_access type:

All of these operands are of an access-to-object type (access Cell, check) whose designated type is Cell (check), Cell has a user-defined primitive equality operator (check) such that

its result type is Boolean (check);
it is declared immediately within the same declaration list as Cell (check); and
at least one of its operands is an access parameter with designated type Cell (both operands are, check).
The preference rule for operator = of the universal_access type in ARM 8.6(29.1) does not apply here, since it requires "two acceptable interpretations". But because of 4.5.2, operator = of the universal_access type is not an acceptable interpretation.

So there is no choice: in all cases (even L = null) it has to be the user-defined operator =.

The example should correctly read:

...

  if Standard."="(L, null) or Standard."="(R, null) then    -- universal =
    return Standard."="(L, R);                              -- universal =
  elsif L.Value = R.Value then
    return L.Next = R.Next;                                 -- recurses OK

...

As Simon Wright pointed out, GNAT seems to run into "unbounded recursion" with the original example, which is actually the correct compiler behavior according to the standard. However SO user G_Zeus mentioned that GNAT issues an ambiguity error for L = R in a similar example, which is incorrect compiler behavior. It should have unambiguously picked the overloaded operator =.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Overloading operator "=" for anonymous access types?
  2019-01-15  8:51       ` daicrkk
@ 2019-01-15 11:15         ` Simon Wright
  0 siblings, 0 replies; 17+ messages in thread
From: Simon Wright @ 2019-01-15 11:15 UTC (permalink / raw)


daicrkk@googlemail.com writes:

>   if Standard."="(L, null) or Standard."="(R, null) then    -- universal =
>     return Standard."="(L, R);                              -- universal =

In my copy of Barnes's book (Programming in Ada 2012) in 11.7, at the
top of p.214, this is stated as the version required by Ada 2005 and to
be "a bit ugly".

One would rather be ugly than wrong.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Overloading operator "=" for anonymous access types?
  2019-01-15  8:38       ` Dmitry A. Kazakov
@ 2019-01-15 21:00         ` Randy Brukardt
  2019-01-16 15:42           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 17+ messages in thread
From: Randy Brukardt @ 2019-01-15 21:00 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:q1k65j$1qqm$1@gioia.aioe.org...
...
> [ The reference manual is shy to say anything about it. It claims that 
> universal_access is kind of class-wide, which would mean, if taken 
> seriously, that "=" overloads and must clash with the original "=".

This is what happens. However, such a clash would mean that you could never 
write a user-defined "=" for an anonymous access type. That would have been 
a good idea, but it would have to have been enforced with a Legality Rule to 
be sensible. Some thought that bad because of compatibility, so...

> Since it does not, universal_access is more like a parent type than 
> class-wide.]

...there is a hack to have a preference for the user-defined one. That 
doesn't change the the fact that universal_access is class-wide, it just 
make it possible to write a user-defined operator.

>P.S. And, wouldn't it be better to fix the type system, no?

This wart would be one of the things that would make "fixing the type 
system" so much harder. A proper solution (and the one we should have used 
in the first place) is to declare a "=" for every access type. I think we 
wanted to avoid that as anonymous access can be declared in places where 
declarations aren't allowed, so we came up with something worse. :-)

It's the idea of anonymous access types that destroys the type system that 
you have in mind. Your system keeps the types and operations together, and 
that makes no sense for an anonymous type (what are the operations for an 
anonymous type, and where are they declared? Any answer is either magical or 
nonsense.)

One has to get rid of nonsense things before one could regularize the type 
system, especially upon the lines you have been suggesting for years. It's 
not really possible for Ada; you would end up with an Ada-like language.

                           Randy.



This is just another Ada 


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Overloading operator "=" for anonymous access types?
  2019-01-15 21:00         ` Randy Brukardt
@ 2019-01-16 15:42           ` Dmitry A. Kazakov
  0 siblings, 0 replies; 17+ messages in thread
From: Dmitry A. Kazakov @ 2019-01-16 15:42 UTC (permalink / raw)


On 2019-01-15 22:00, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
> news:q1k65j$1qqm$1@gioia.aioe.org...
> ...
>> [ The reference manual is shy to say anything about it. It claims that
>> universal_access is kind of class-wide, which would mean, if taken
>> seriously, that "=" overloads and must clash with the original "=".
> 
> This is what happens. However, such a clash would mean that you could never
> write a user-defined "=" for an anonymous access type. That would have been
> a good idea, but it would have to have been enforced with a Legality Rule to
> be sensible. Some thought that bad because of compatibility, so...
> 
>> Since it does not, universal_access is more like a parent type than
>> class-wide.]
> 
> ...there is a hack to have a preference for the user-defined one. That
> doesn't change the the fact that universal_access is class-wide, it just
> make it possible to write a user-defined operator.

Yes, you need hacks to handle inconsistencies and weaknesses.

>> P.S. And, wouldn't it be better to fix the type system, no?
> 
> This wart would be one of the things that would make "fixing the type
> system" so much harder. A proper solution (and the one we should have used
> in the first place) is to declare a "=" for every access type. I think we
> wanted to avoid that as anonymous access can be declared in places where
> declarations aren't allowed, so we came up with something worse. :-)

I think the problem is that all operations with access T as an argument 
should be primitive operations of T. That was the idea behind anonymous 
access types all the time. But some types are not so much types to have 
classes.

> It's the idea of anonymous access types that destroys the type system that
> you have in mind. Your system keeps the types and operations together, and
> that makes no sense for an anonymous type (what are the operations for an
> anonymous type, and where are they declared? Any answer is either magical or
> nonsense.)

Yes, there is a conflict between anonymous access type treated as a 
standalone type and as a parameter passing mode of the target type.

> One has to get rid of nonsense things before one could regularize the type
> system, especially upon the lines you have been suggesting for years. It's
> not really possible for Ada; you would end up with an Ada-like language.

We may be able to express this in the terms of a more general type 
system. If anonymous access would be a mere user-defined type with all 
its perks that would be OK.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Overloading operator "=" for anonymous access types?
  2019-01-14 23:08     ` Overloading operator "=" " Randy Brukardt
                         ` (2 preceding siblings ...)
  2019-01-15  8:51       ` daicrkk
@ 2019-01-17  3:20       ` Jere
  2019-01-17  8:23         ` Dmitry A. Kazakov
  2019-01-17 22:22         ` Randy Brukardt
  3 siblings, 2 replies; 17+ messages in thread
From: Jere @ 2019-01-17  3:20 UTC (permalink / raw)


On Monday, January 14, 2019 at 6:08:36 PM UTC-5, Randy Brukardt wrote:
> As always, best avoid anonymous access types unless you have to use one of 
> their special features (dynamic accessibility, dispatching, special 
> discriminant accessibility, or closures [for access-to-subprograms]). And 
> better still, lets lobby to get those special features optionally available 
> for named access types so no one every has to use an anonymous anything. :-)
> 
>                                           Randy.

I mostly find myself using them in situations where I need to save an 
access variable of an object that doesn't live as long as the access
type involved.  I can't do that safely with named access types.  For
example, using them in containers (need the access type for iterators,
cursors, etc.) but creating those container objects inside an operation 
of some form.  I feel like having to use Unchecked_Access somewhat
defeats the purpose of using Ada (not all of it, just some).

Are there any plans to add smarter and more relaxed named access types
in the future?  Something akin to rust references (especially with
the recently released non lexical lifetimes update)?  It's definitely
possible to track references in such a way though I wouldn't claim 
it was easy to do.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Overloading operator "=" for anonymous access types?
  2019-01-17  3:20       ` Jere
@ 2019-01-17  8:23         ` Dmitry A. Kazakov
  2019-01-17 22:22         ` Randy Brukardt
  1 sibling, 0 replies; 17+ messages in thread
From: Dmitry A. Kazakov @ 2019-01-17  8:23 UTC (permalink / raw)


On 2019-01-17 04:20, Jere wrote:

> I mostly find myself using them in situations where I need to save an
> access variable of an object that doesn't live as long as the access
> type involved.  I can't do that safely with named access types.  For
> example, using them in containers (need the access type for iterators,
> cursors, etc.)

Actually access discriminant meant to be long living, a mix-in hack to 
avoid multiple inheritance implementation.

> but creating those container objects inside an operation
> of some form.  I feel like having to use Unchecked_Access somewhat
> defeats the purpose of using Ada (not all of it, just some).

That is yet another hack. You should have been able to use a limited 
type object as a discriminant straight away without pointers. The 
situation is just same as with access to subprogram types. You would not 
need them most of the time, if you could pass subprogram as a parameter.

> Are there any plans to add smarter and more relaxed named access types
> in the future?  Something akin to rust references (especially with
> the recently released non lexical lifetimes update)?  It's definitely
> possible to track references in such a way though I wouldn't claim
> it was easy to do.

There is no need in an access type in these situations, why naming it?

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Overloading operator "=" for anonymous access types?
  2019-01-17  3:20       ` Jere
  2019-01-17  8:23         ` Dmitry A. Kazakov
@ 2019-01-17 22:22         ` Randy Brukardt
  2019-01-18 10:17           ` Dmitry A. Kazakov
  2019-01-18 13:27           ` Jere
  1 sibling, 2 replies; 17+ messages in thread
From: Randy Brukardt @ 2019-01-17 22:22 UTC (permalink / raw)


"Jere" <jhb.chat@gmail.com> wrote in message 
news:252afc47-fe7d-41bc-b394-0735e1fd2e4c@googlegroups.com...
...
> I mostly find myself using them in situations where I need to save an
> access variable of an object that doesn't live as long as the access
> type involved.  I can't do that safely with named access types.

You should have just stopped at "safely": "I can't do that safely." So far 
as I know, the only way to do that with anonymous access (other than 
parameters) is to used Unchecked_Access. And in the case of the parameters, 
you should just have passed the designated object.

> For
> example, using them in containers (need the access type for iterators,
> cursors, etc.) but creating those container objects inside an operation
> of some form.  I feel like having to use Unchecked_Access somewhat
> defeats the purpose of using Ada (not all of it, just some).

Ada accessibility checks are designed for a particular use case: that of 
programs that cannot allow dynamically allocated objects but still need 
accesses. In such a case, all of the objects are typically globally 
allocated and managed in some way.

For most other uses, the best thing to do with accessibility checks is turn 
them off. You have to dynamically manage lifetime in that case (usually 
using a controlled type to do it), and accessibility provides nothing in 
that case. And you turn off accessibility checks by using 'Unchecked_Access.

For the most part, I personally view accessibility checks as a mistake, but 
then again I never write programs in the first category. So I have to take 
others word for it that it is useful there. Dynamic accessibility provides 
nothing but overhead and tripping hazards (the possibility of a mysterious 
exception in otherwise tested code).

> Are there any plans to add smarter and more relaxed named access types
> in the future?  Something akin to rust references (especially with
> the recently released non lexical lifetimes update)?  It's definitely
> possible to track references in such a way though I wouldn't claim
> it was easy to do.

There won't be anything significant in Ada 2020; we're too close to the end 
game for that to be able to do the experimentation with different designs 
that is still needed. We have a few proposals for "smarter" access type, but 
no one would call them "more relaxed". The basic idea is to use additional 
compile-time and run-time restrictions to allow automatic deallocation and 
to eliminate the possibility of dangling references.

I'm pretty sure there never will be "more relaxed" access types, as there is 
a substantial community within Ada that would never allow making Ada 
features less safe (that is, having more erroneous cases). I suppose one 
could call a named access type that using only dynamic accessibility checks 
"more relaxed", but all that would do is add a lot of overhead to access 
types in order to convert a compile-time check into a runtime one (read new 
way to have a program fail).

I'd like to see a way to allow named access types to have the various 
special behaviors associated only with anonymous access types today, but I 
certainly would not characterize that as "more relaxed".

                                          Randy.

P.S. I agree with Dmitry that in many of these cases you don't want to use 
access types at all. Most ADT interfaces are better off taking the ADT 
objects directly; leave the client to organizing structures. When you use 
access types in the interface, you force all clients to use access types in 
their usage; it's better to let them decide whether scoping, containers, or 
access types are the best way to manage the objects. (Definitely the most 
reusable.) (And no, I don't consider forcing clients to use 
'Unchecked_Access all over the place as a way for them to avoid using access 
types.)





^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Overloading operator "=" for anonymous access types?
  2019-01-17 22:22         ` Randy Brukardt
@ 2019-01-18 10:17           ` Dmitry A. Kazakov
  2019-01-18 13:27           ` Jere
  1 sibling, 0 replies; 17+ messages in thread
From: Dmitry A. Kazakov @ 2019-01-18 10:17 UTC (permalink / raw)


On 2019-01-17 23:22, Randy Brukardt wrote:

> Ada accessibility checks are designed for a particular use case: that of
> programs that cannot allow dynamically allocated objects but still need
> accesses.

A great succinct formulation everybody must keep in mind to avoid 
misunderstandings!

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Overloading operator "=" for anonymous access types?
  2019-01-17 22:22         ` Randy Brukardt
  2019-01-18 10:17           ` Dmitry A. Kazakov
@ 2019-01-18 13:27           ` Jere
  2019-01-18 13:42             ` Dmitry A. Kazakov
  1 sibling, 1 reply; 17+ messages in thread
From: Jere @ 2019-01-18 13:27 UTC (permalink / raw)


On Thursday, January 17, 2019 at 5:22:49 PM UTC-5, Randy Brukardt wrote:
> "Jere" wrote in message 
> ...
> > I mostly find myself using them in situations where I need to save an
> > access variable of an object that doesn't live as long as the access
> > type involved.  I can't do that safely with named access types.
> 
> You should have just stopped at "safely": "I can't do that safely." So far 
> as I know, the only way to do that with anonymous access (other than 
> parameters) is to used Unchecked_Access. And in the case of the parameters, 
> you should just have passed the designated object.

It can be done safely, but just not using Ada's current paradigm. There
are other safety minded languages that have figured out how to do it
without needing to check against their equivalent of an access type's
lifetime.  They can do it based on the lifetime of the actual
[their equivalent to] access object vs the lifetime of the object it 
points to (at compile time).

> 
> > For
> > example, using them in containers (need the access type for iterators,
> > cursors, etc.) but creating those container objects inside an operation
> > of some form.  I feel like having to use Unchecked_Access somewhat
> > defeats the purpose of using Ada (not all of it, just some).
> 
> Ada accessibility checks are designed for a particular use case: that of 
> programs that cannot allow dynamically allocated objects but still need 
> accesses. In such a case, all of the objects are typically globally 
> allocated and managed in some way.
Which is particularly important in bare metal environments and smaller
embedded environments as well.  Even just messing around with some custom
bounded containers leads me down this rabbit hole.

> 
> <SNIPPED>
> 
> > Are there any plans to add smarter and more relaxed named access types
> > in the future?  Something akin to rust references (especially with
> > the recently released non lexical lifetimes update)?  It's definitely
> > possible to track references in such a way though I wouldn't claim
> > it was easy to do.
> 
> There won't be anything significant in Ada 2020; we're too close to the end 
> game for that to be able to do the experimentation with different designs 
> that is still needed. We have a few proposals for "smarter" access type, but 
> no one would call them "more relaxed". The basic idea is to use additional 
> compile-time and run-time restrictions to allow automatic deallocation and 
> to eliminate the possibility of dangling references.
That would be nice.   I think the biggest hurdle to named access types for
me is that the object has to live as long as the access type.  That forces
you into using the equivalent of global variables a lot of time.  At least
in Ada they have separate scopes to help with naming clashes, but it doesn't
protect you from having someone misuse a variable outside of its intent.
> 
> I'm pretty sure there never will be "more relaxed" access types, as there is 
> a substantial community within Ada that would never allow making Ada 
> features less safe (that is, having more erroneous cases). I suppose one 
> could call a named access type that using only dynamic accessibility checks 
> "more relaxed", but all that would do is add a lot of overhead to access 
> types in order to convert a compile-time check into a runtime one (read new 
> way to have a program fail).
More relaxed doesn't necessarily mean less safe.  It can even be more safe.
The less relaxed Ada paradigm can force you to provide a variable outside
of a scope that it is intended to be used in, which is a maintenance hazard.


> 
> P.S. I agree with Dmitry that in many of these cases you don't want to use 
> access types at all. Most ADT interfaces are better off taking the ADT 
> objects directly; leave the client to organizing structures. When you use 
> access types in the interface, you force all clients to use access types in 
> their usage; it's better to let them decide whether scoping, containers, or 
> access types are the best way to manage the objects. (Definitely the most 
> reusable.) (And no, I don't consider forcing clients to use 
> 'Unchecked_Access all over the place as a way for them to avoid using access 
> types.)

I don't like using access types at all, but Ada requires it sometimes.  Just
making a cursor or iterator to a custom container requires it.  And if your
type is not limited, you start getting pushed more into unchecked_access
since you don't have handy tricks like the Rosen Technique.  Conversely,
if you need to keep an array of dispatchable limited types, you have to use
access types (indefinite containers doesn't work on limited types).  I 
don't like to use them in public interfaces at all, so I avoid that, but it
is hard to avoid in implementation and harder still to ensure it is done
right.  My hope is Ada eventually makes that both safe and more maintenance 
friendly in the future, for the times where you have to use them.

Note, I am not saying that Ada has any serious problems, but am just
wishing there was better support for using access types with non heap
objects (for the times that you have to).

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Overloading operator "=" for anonymous access types?
  2019-01-18 13:27           ` Jere
@ 2019-01-18 13:42             ` Dmitry A. Kazakov
  0 siblings, 0 replies; 17+ messages in thread
From: Dmitry A. Kazakov @ 2019-01-18 13:42 UTC (permalink / raw)


On 2019-01-18 14:27, Jere wrote:

> Note, I am not saying that Ada has any serious problems, but am just
> wishing there was better support for using access types with non heap
> objects (for the times that you have to).

No. Ada should not force access types where they are not needed. E.g. 
the cases where a language-managed reference would suffice.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2019-01-18 13:42 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-11 21:46 Overloading operator “=” for anonymous access types? daicrkk
2019-01-12  9:50 ` Simon Wright
2019-01-12 14:01   ` Simon Wright
2019-01-12 15:15   ` daicrkk
2019-01-14 23:08     ` Overloading operator "=" " Randy Brukardt
2019-01-15  0:34       ` Shark8
2019-01-15  8:38       ` Dmitry A. Kazakov
2019-01-15 21:00         ` Randy Brukardt
2019-01-16 15:42           ` Dmitry A. Kazakov
2019-01-15  8:51       ` daicrkk
2019-01-15 11:15         ` Simon Wright
2019-01-17  3:20       ` Jere
2019-01-17  8:23         ` Dmitry A. Kazakov
2019-01-17 22:22         ` Randy Brukardt
2019-01-18 10:17           ` Dmitry A. Kazakov
2019-01-18 13:27           ` Jere
2019-01-18 13:42             ` Dmitry A. Kazakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox