comp.lang.ada
 help / color / mirror / Atom feed
* Subverting 'Access for Sub-programs
@ 1999-08-03  0:00 Anton Gibbs
  1999-08-03  0:00 ` tmoran
                   ` (7 more replies)
  0 siblings, 8 replies; 68+ messages in thread
From: Anton Gibbs @ 1999-08-03  0:00 UTC (permalink / raw)


Dear Ada Community,

Can someone please advise me on the best way to subvert the language
rules that prevent the use of 'Access on a locally declared procedure ?

For normal objects it is possible to use 'Unchecked_Access but for
sub-programs this is not allowed.

"Why does this idiot want to do this ?" I hear you ask.

Well it seemed reasonable enough to me within a wider application, the
essence of which I have distilled into a few lines below.

package Database is
   type Action_Type is access procedure( I : in Integer );
   -- Perform calls Action for every entry in the database
   procedure Perform( Action : in Action_Type );
end Database;

with Database;
with Text_IO;
procedure Main is
   procedure Print_If_Even( I : in Integer ) is
   begin
      if I rem 2 = 0 then
         Text_IO.Put_Line( Integer'Image( I ) );
      end if;
   end Print_If_Even;
begin
   Database.Perform( Action => Print_If_Even'Access );
end Main;

The offending statement is the one containing the 'Access because
Print_If_Even is declared at deeper level than it.

So how can I achieve what I need here (ie. visibility of parameter I)
without either: a) using global data and making the whole thing
unnecessarily non-reentrant; or b) recourse to the usual generic
contortions which I thought Ada95's procedure access types had allowed
us to escape from ? I am sure someone else must have run into this
problem before and that there is an accepted way of tackling it.

Thanks for any help you can offer.

Best regards

Anton Gibbs.
Software Engineer

-- 
Civil Air Traffic Management Group
Defence Evaluation and Research Agency
Bedford, UK

"The Information contained in this E-Mail and any 
subsequent correspondence is private and is intended
solely for the intended recipient(s).  For those
other than the intended recipient any disclosure,
copying, distribution, or any action taken or 
omitted to be taken in reliance on such information
is prohibited and may be unlawful."




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

* Re: Subverting 'Access for Sub-programs
  1999-08-03  0:00 Subverting 'Access for Sub-programs Anton Gibbs
  1999-08-03  0:00 ` tmoran
  1999-08-03  0:00 ` Steve Doiel
@ 1999-08-03  0:00 ` Ted Dennison
  1999-08-03  0:00 ` David C. Hoos, Sr.
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 68+ messages in thread
From: Ted Dennison @ 1999-08-03  0:00 UTC (permalink / raw)


In article <37A71EF1.2201@dera.gov.uk>,
  Anton Gibbs <agibbs@dera.gov.uk> wrote:

> The offending statement is the one containing the 'Access because
> Print_If_Even is declared at deeper level than it.
>
> So how can I achieve what I need here (ie. visibility of parameter I)
> without either: a) using global data and making the whole thing
> unnecessarily non-reentrant; or b) recourse to the usual generic
> contortions which I thought Ada95's procedure access types had allowed

Easy. Declare your accessed routine at the top level of a package.

I've run into this several times. Every time it was when I was trying to
write a toy example or a test driver. Under normal circumstances the
client of your package will probably be another package anyway.

--
T.E.D.


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-03  0:00 Subverting 'Access for Sub-programs Anton Gibbs
@ 1999-08-03  0:00 ` tmoran
  1999-08-03  0:00 ` Steve Doiel
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 68+ messages in thread
From: tmoran @ 1999-08-03  0:00 UTC (permalink / raw)


Remember that Database.Perform is completely within its rights to
save away the Action parameter and call Action later.  It might
save it in a variable, or, more subtly, hand it to a task which
will use it after Action no longer exists.  A jump into random
junk is not a very nice way for a program to crash.

To avoid the problem, how about:

package Dont_Disappear is
   procedure Print_If_Even( I : in Integer );
end Dont_Disappear;

with Text_IO;
package body Dont_Disappear is
   procedure Print_If_Even( I : in Integer ) is
   begin
      if I rem 2 = 0 then
         Text_IO.Put_Line( Integer'Image( I ) );
      end if;
   end Print_If_Even;
end Dont_Disappear;

with Database,
     Dont_Disappear;
procedure Main is
begin
   Database.Perform( Action => Dont_Disappear.Print_If_Even'Access );
end Main;




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

* Re: Subverting 'Access for Sub-programs
  1999-08-03  0:00 Subverting 'Access for Sub-programs Anton Gibbs
                   ` (3 preceding siblings ...)
  1999-08-03  0:00 ` David C. Hoos, Sr.
@ 1999-08-03  0:00 ` Michael F. Yoder
  1999-08-03  0:00 ` Brian Rogoff
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 68+ messages in thread
From: Michael F. Yoder @ 1999-08-03  0:00 UTC (permalink / raw)


Anton Gibbs wrote:
> 
> Dear Ada Community,
> 
> Can someone please advise me on the best way to subvert the language
> rules that prevent the use of 'Access on a locally declared procedure?
> ...

Is the following rearranged version, which compiled and ran using GNAT,
sufficient?  If not, is there something missing from your example that
shows your problem more exactly?

package Database is
   type Action_Type is access procedure( I : in Integer );
   -- Perform calls Action for every entry in the database
   procedure Perform( Action : in Action_Type );
end Database;

package body Database is
   procedure Perform( Action : in Action_Type ) is
   begin
      for I in 1 .. 10 loop
         Action.all(I);
      end loop;
   end Perform;
end Database;

package p is
   procedure Print_If_Even( I : in Integer );
end p;

with Ada.Text_IO;
package body p is
   procedure Print_If_Even( I : in Integer ) is
   begin
      if I rem 2 = 0 then
         Ada.Text_IO.Put_Line( Integer'Image( I ) );
      end if;
   end Print_If_Even;
end p;

with Database;
with p;
procedure Main is
begin
   Database.Perform( Action => p.Print_If_Even'Access );
end Main;

-- 
Michael F. Yoder

Unscientific man is beset by a deplorable desire to have been right.
The scientist is distinguished by a desire to *be* right. -- W.V. Quine




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

* Re: Subverting 'Access for Sub-programs
  1999-08-03  0:00 Subverting 'Access for Sub-programs Anton Gibbs
                   ` (2 preceding siblings ...)
  1999-08-03  0:00 ` Ted Dennison
@ 1999-08-03  0:00 ` David C. Hoos, Sr.
  1999-08-05  0:00   ` Robert A Duff
  1999-08-03  0:00 ` Michael F. Yoder
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 68+ messages in thread
From: David C. Hoos, Sr. @ 1999-08-03  0:00 UTC (permalink / raw)



Anton Gibbs wrote in message <37A71EF1.2201@dera.gov.uk>...
>Dear Ada Community,
>
>Can someone please advise me on the best way to subvert the language
>rules that prevent the use of 'Access on a locally declared procedure ?
>
>For normal objects it is possible to use 'Unchecked_Access but for
>sub-programs this is not allowed.
>
>"Why does this idiot want to do this ?" I hear you ask.
>
>Well it seemed reasonable enough to me within a wider application, the
>essence of which I have distilled into a few lines below.
>

The real problem is that the compiler cannnot know that procedure Main
will have a lifetime as long as the entire program -- for there is
nothing that says (at _compile_ time) that procedure Main is the _Main_
procedure.

Since the subprogram to which you wish to provide access is nested
within this procedure, its lifetime cannot be guaranteed _at compile
time_ to exceed the lifetime of the subprogram(s) to which the
access is passed.

The solution is simply to declare the procedure Print_If_Even at
library level -- either in a library-level package, or as a
standalone library procedure.

So... no subversion is necessary - just adhere as described, and
you'll be fine.








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

* Re: Subverting 'Access for Sub-programs
  1999-08-03  0:00 Subverting 'Access for Sub-programs Anton Gibbs
  1999-08-03  0:00 ` tmoran
@ 1999-08-03  0:00 ` Steve Doiel
  1999-08-03  0:00 ` Ted Dennison
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 68+ messages in thread
From: Steve Doiel @ 1999-08-03  0:00 UTC (permalink / raw)


You already had a number of valid responses to your question, but none
seem to subvert the language.  I'm not sure mine does, but here goes
anyway:

For your main procedure use (exactly as shown):

with Main_Package;
procedure EntryPoint is
begin
   Main_Package.Main;
end EntryPoint;

For your program use a package spec and body:

package Main_Package is
  procedure Main;
end Main_Package;

with Database;
with Ada.Text_Io;
package body Main_Package is

  package Text_IO renames Ada.Text_IO;

  procedure Print_If_Even( I : in Integer ) is
  begin
     if I rem 2 = 0 then
        Text_IO.Put_Line( Integer'Image( I ) );
     end if;
  end Print_If_Even;

  procedure Main is
  begin
    Database.Perform( Action => Print_If_Even'Access );
  end Main;

end Main_Package;

In this code use Main_Package.Main as a substitute for your
main procedure.  This allows you to define Print_If_Even at
the library level (outside of any other procedure).

FWIW

SteveD






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

* Re: Subverting 'Access for Sub-programs
  1999-08-03  0:00 Subverting 'Access for Sub-programs Anton Gibbs
                   ` (4 preceding siblings ...)
  1999-08-03  0:00 ` Michael F. Yoder
@ 1999-08-03  0:00 ` Brian Rogoff
  1999-08-04  0:00 ` Robert Dewar
  1999-08-04  0:00 ` Anton Gibbs
  7 siblings, 0 replies; 68+ messages in thread
From: Brian Rogoff @ 1999-08-03  0:00 UTC (permalink / raw)


On Tue, 3 Aug 1999, Anton Gibbs wrote:

> Dear Ada Community,
> 
> Can someone please advise me on the best way to subvert the language
> rules that prevent the use of 'Access on a locally declared procedure ?

I'm looking forward to a week where this question is asked every day :-). 

> For normal objects it is possible to use 'Unchecked_Access but for
> sub-programs this is not allowed.
> 
> "Why does this idiot want to do this ?" I hear you ask.

Not at all. Any idiot who has ever used Pascal can do this, as can any
idiotic user of a functional programming language, though, to be fair, the 
FPers pay for that in general with garbage collection. 

If you use GNAT, Unrestricted_Access does what you want. You have
suggested generic contortions, others suggest hauling the offending
function up to library level, and then offer excuses as to why Ada has 
this big wart, sometimes even justifying the wart by arguing that these 
contortions are a good idea. Robert Dewar explains the "why" of the
access rules in his post, and the reason for the fondness for displays
over static links goes back to the requirements for Ada 83. Another
workaround is to use tagged types,  but since you can't extend them
locally either it isn't often too helpful. 

The consolation here is that neither C++ nor Java even have nested
functions. 

-- Brian





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

* Re: Subverting 'Access for Sub-programs
  1999-08-03  0:00 Subverting 'Access for Sub-programs Anton Gibbs
                   ` (6 preceding siblings ...)
  1999-08-04  0:00 ` Robert Dewar
@ 1999-08-04  0:00 ` Anton Gibbs
  1999-08-04  0:00   ` Robert A Duff
                     ` (2 more replies)
  7 siblings, 3 replies; 68+ messages in thread
From: Anton Gibbs @ 1999-08-04  0:00 UTC (permalink / raw)


Dear Ada Community,

Thank you, everyone, for all the very helpful responses to my question
on 'Access.

Unfortunately, in my eagerness to provide a simplified statement of my
problem, I had omitted an important detail: in fact, the procedure which
I called Main is really not the main program and, more importantly, it
has a parameter which I need to access.

What I mean is:-

package Database is
   type Action_Type is access procedure( I : in Integer );
   -- Perform calls Action for every entry in the database
   procedure Perform( Action : in Action_Type );
end Database;

with Database;
with Text_IO;
package body Something is
   procedure Not_Main( F : in Integer ) is
      procedure Print_If_Multiple( I : in Integer ) is
      begin
         if I rem F = 0 then
            Text_IO.Put_Line( Integer'Image( I ) );
         end if;
      end Print_If_Multiple;
   begin
      Database.Perform( Action => Print_If_Multiple'Access );
   end Not_Main;
end Something;

Here, the problem is retaining visibility of the parameter F within the
procedure whose 'Access I am trying to pass to the Perform operation. If
I move Print_If_Multiple out to its own package (ie. out of the scope of
Not_Main) then the only way I can see F is by using global data. I know
this will work but I am reluctant to adopt this approach because I have
often found that non-re-entrant code bites back in years to come when it
gets re-used (usually by me) in a way the author never originally
intended.

I am attracted by Robert Dewar's 'Unrestricted_Access: it is obviously
there for a reason. Thank you too for the candid explanation of why
'Unchecked_Access is prohibited on sub-programs. As someone who is often
baffled by some of the language restrictions it is nice to get an
explanation one can understand. I just wish I could understand the Ada95
LRM as well as I could the Ada83 one.

Many thanks everyone.

Regards

Anton Gibbs.
Software Engineer

-- 
Civil Air Traffic Management Group
Defence Evaluation and Research Agency
Bedford, UK

"The Information contained in this E-Mail and any 
subsequent correspondence is private and is intended
solely for the intended recipient(s).  For those
other than the intended recipient any disclosure,
copying, distribution, or any action taken or 
omitted to be taken in reliance on such information
is prohibited and may be unlawful."




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

* Re: Subverting 'Access for Sub-programs
  1999-08-04  0:00 ` Robert Dewar
@ 1999-08-04  0:00   ` Robert A Duff
  1999-08-04  0:00     ` Robert Dewar
  0 siblings, 1 reply; 68+ messages in thread
From: Robert A Duff @ 1999-08-04  0:00 UTC (permalink / raw)


Robert Dewar <dewar@gnat.com> writes:

> P.S. We have found Unrestricted_Access to be vital for
> implementing some of our run time and library packages (see
> for example the implementation of GNAT.Spitbol.Patterns in
> g-spipat.ads/adb files)

Robert,

Please explain why generic formal subprograms are not sufficient for
this purpose.  During the design, that was the main rationale for why we
don't need downward closures (which I didn't buy, by the way).

- Bob
-- 
Change robert to bob to get my real email address.  Sorry.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-04  0:00 ` Anton Gibbs
@ 1999-08-04  0:00   ` Robert A Duff
  1999-08-04  0:00     ` Brian Rogoff
  1999-08-05  0:00     ` Anton Gibbs
  1999-08-04  0:00   ` Jean-Pierre Rosen
  1999-08-05  0:00   ` Steve Quinlan
  2 siblings, 2 replies; 68+ messages in thread
From: Robert A Duff @ 1999-08-04  0:00 UTC (permalink / raw)


Anton Gibbs <agibbs@dera.gov.uk> writes:

> Here, the problem is retaining visibility of the parameter F within the
> procedure whose 'Access I am trying to pass to the Perform operation. If
> I move Print_If_Multiple out to its own package (ie. out of the scope of
> Not_Main) then the only way I can see F is by using global data. I know
> this will work but I am reluctant to adopt this approach because I have
> often found that non-re-entrant code bites back in years to come when it
> gets re-used (usually by me) in a way the author never originally
> intended.

There is no good solution to this problem: no solution that is portable,
concise, reentrant, &c.

One thing you can do is declare a tagged type, and use an extension as
the environment of the procedure you want to pass -- then instead of
passing a procedure as a parameter, pass an object of the class-wide
type.

> "The Information contained in this E-Mail and any 
> subsequent correspondence is private and is intended
> solely for the intended recipient(s). ...

 :-) :-) :-)

- Bob
-- 
Change robert to bob to get my real email address.  Sorry.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-04  0:00   ` Robert A Duff
@ 1999-08-04  0:00     ` Robert Dewar
  0 siblings, 0 replies; 68+ messages in thread
From: Robert Dewar @ 1999-08-04  0:00 UTC (permalink / raw)


In article <wccd7x3g08n.fsf@world.std.com>,
  Robert A Duff <bobduff@world.std.com> wrote:
> Robert Dewar <dewar@gnat.com> writes:
>
> > P.S. We have found Unrestricted_Access to be vital for
> > implementing some of our run time and library packages (see
> > for example the implementation of GNAT.Spitbol.Patterns in
> > g-spipat.ads/adb files)
>
> Robert,
>
> Please explain why generic formal subprograms are not
sufficient for
> this purpose.  During the design, that was the main rationale
for why we
> don't need downward closures (which I didn't buy, by the way).



I have not the foggiest idea what you are talking about, the
use of this attribute in the patterns implementation has very
little to do with downward closures. If you think you could
replace the usage there with formal subprograms, you are welcome
to try (it would be nice because they nyou could use this
package on the Rational compiler for example).

But I can't explain to you why I can't do something that I
don't even begin to see could be done :-)

Robert Dewar
Ada Core Technologies


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-04  0:00   ` Jean-Pierre Rosen
@ 1999-08-04  0:00     ` Brian Rogoff
  1999-08-05  0:00       ` Jean-Pierre Rosen
  1999-08-05  0:00     ` Robert A Duff
  1 sibling, 1 reply; 68+ messages in thread
From: Brian Rogoff @ 1999-08-04  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: TEXT/PLAIN; charset=X-UNKNOWN, Size: 2670 bytes --]

On Wed, 4 Aug 1999, Jean-Pierre Rosen wrote:
> Anton Gibbs <agibbs@dera.gov.uk> a écrit dans le message :
> 37A7FDE8.4F5@dera.gov.uk...
> > Dear Ada Community,
> >
> > Thank you, everyone, for all the very helpful responses to my question
> > on 'Access.
> >
> > Unfortunately, in my eagerness to provide a simplified statement of my
> > problem, I had omitted an important detail: in fact, the procedure which
> > I called Main is really not the main program and, more importantly, it
> > has a parameter which I need to access.
> >
> [snip]
> I understood from a previous message that you didn't like the solution with
> a generic taking a formal procedure.
> It seems however that it would allow you to do precisely what you want.
> You may not "like" generics, but they are inherently safer than access
> values. Actually, in the discussion about downward closures, it was noted
> that all the cases presented could be equally well be dealt with with
> generics, and therefore that it was not worth introducing a risky feature.

Not true for any reasonable value of "equally well". For instance, in one
of those ancient postings of a few years ago on this very topic Richard
O'Keefe presented the example of making a two dimensional integrator from 
a one dimensional one. The Ada version with generics depended on the name
of the one dimensional integratoir, and so it was parameterized by that
particular integrator. The downward closure one was free to range over all 
one dimensional integrators. I'll append the code, if you can come up with
a perspicuous generic version that doesn't depend on the one dimensional
code I'll be more convinced. 

I think its also true that in the typical implementation of generics there 
will be a code size problem too. 

-- Brian

    type Func1_Type        is access function(X : Float) return Float;
    type Func2_Type        is access function(X,Y : Float) return Float;
    type Integrate_1D_Type is access function(X,Y : Float; 
					      F : Func1_Type) 
        return Float;

    function Integrate_1D(L1, U1 : Float;
			  F     :  Func1_Type) return Float is 
	-- some locals 
    begin
	-- some 1-D integrator 
    end;

    function Integrate_2D(L1, U1, L2, U2: Float;
			  Integrator : Integrate_1D_Type;
			  Func : Func2_Type ) return Float is 
	function Inner(Y: Float) return  Float is 
	    function Curried_F(X: Float) return Float is 
	    begin 
		return Func(X, Y) 
	    end;
	begin 
	    return Integrator(L1, U1, Curried_F'Unrestricted_Access) 
	end;
    begin 
	return Integrator(L2, U2, Inner'Unrestricted_Access) 
    end;






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

* Re: Subverting 'Access for Sub-programs
  1999-08-04  0:00   ` Robert A Duff
@ 1999-08-04  0:00     ` Brian Rogoff
  1999-08-05  0:00       ` tmoran
  1999-08-05  0:00     ` Anton Gibbs
  1 sibling, 1 reply; 68+ messages in thread
From: Brian Rogoff @ 1999-08-04  0:00 UTC (permalink / raw)


On Wed, 4 Aug 1999, Robert A Duff wrote:
> Anton Gibbs <agibbs@dera.gov.uk> writes:
> 
> > Here, the problem is retaining visibility of the parameter F within the
> > procedure whose 'Access I am trying to pass to the Perform operation. If
> > I move Print_If_Multiple out to its own package (ie. out of the scope of
> > Not_Main) then the only way I can see F is by using global data. I know
> > this will work but I am reluctant to adopt this approach because I have
> > often found that non-re-entrant code bites back in years to come when it
> > gets re-used (usually by me) in a way the author never originally
> > intended.
> 
> There is no good solution to this problem: no solution that is portable,
> concise, reentrant, &c.
> 
> One thing you can do is declare a tagged type, and use an extension as
> the environment of the procedure you want to pass -- then instead of
> passing a procedure as a parameter, pass an object of the class-wide
> type.

This workaround would be a lot more effective if you could extend the
tagged type at a deeper accessibility level than the parent. But you know 
that :-)

-- Brian






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

* Re: Subverting 'Access for Sub-programs
  1999-08-03  0:00 Subverting 'Access for Sub-programs Anton Gibbs
                   ` (5 preceding siblings ...)
  1999-08-03  0:00 ` Brian Rogoff
@ 1999-08-04  0:00 ` Robert Dewar
  1999-08-04  0:00   ` Robert A Duff
  1999-08-04  0:00 ` Anton Gibbs
  7 siblings, 1 reply; 68+ messages in thread
From: Robert Dewar @ 1999-08-04  0:00 UTC (permalink / raw)


In article <37A71EF1.2201@dera.gov.uk>,
  Anton Gibbs <agibbs@dera.gov.uk> wrote:
> Dear Ada Community,

> Can someone please advise me on the best way to subvert the
> language rules that prevent the use of 'Access on a locally
> declared procedure ?

> For normal objects it is possible to use 'Unchecked_Access but
> for sub-programs this is not allowed.

The problem is that the equivalent of Unchecked_Access for
subprograms is not at all easy to implement if you are using
displays. The restrictions in the language regarding access to
nested procedures are indeed semantically unnecessary. This was
one of the few places where the design of the language was quite
conciously compromised because of the strong representations
from implementors (notably Alsys [Aonix], and RR) who used
displays and argued that anything that would make the use of
displays tricky was unacceptable. The design process was
certainly in the business of taking vendor input into
consideration (we all recognized that a marvelous language that
people could not implement was not desirable :-)

If you use static links, then it is indeed easy to implement
both the safe versions proposed by the mapping team, and/or
a version of unchecked_access that works for subprograms.

Since GNAT uses static links, it is indeed easy to implement,
and GNAT has an implementation defined attribute
Unrestricted_Access that may indeed be applied to subprograms to
obtain the effect you want. This is of course unsafe, in the
sense that you can have (and use!) dangling subprogram pointers,
so user beware!

Robert Dewar
Ada Core Technologies

P.S. We have found Unrestricted_Access to be vital for
implementing some of our run time and library packages (see
for example the implementation of GNAT.Spitbol.Patterns in
g-spipat.ads/adb files)


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-04  0:00 ` Anton Gibbs
  1999-08-04  0:00   ` Robert A Duff
@ 1999-08-04  0:00   ` Jean-Pierre Rosen
  1999-08-04  0:00     ` Brian Rogoff
  1999-08-05  0:00     ` Robert A Duff
  1999-08-05  0:00   ` Steve Quinlan
  2 siblings, 2 replies; 68+ messages in thread
From: Jean-Pierre Rosen @ 1999-08-04  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1124 bytes --]


Anton Gibbs <agibbs@dera.gov.uk> a �crit dans le message :
37A7FDE8.4F5@dera.gov.uk...
> Dear Ada Community,
>
> Thank you, everyone, for all the very helpful responses to my question
> on 'Access.
>
> Unfortunately, in my eagerness to provide a simplified statement of my
> problem, I had omitted an important detail: in fact, the procedure which
> I called Main is really not the main program and, more importantly, it
> has a parameter which I need to access.
>
[snip]
I understood from a previous message that you didn't like the solution with
a generic taking a formal procedure.
It seems however that it would allow you to do precisely what you want.
You may not "like" generics, but they are inherently safer than access
values. Actually, in the discussion about downward closures, it was noted
that all the cases presented could be equally well be dealt with with
generics, and therefore that it was not worth introducing a risky feature.

--
---------------------------------------------------------
           J-P. Rosen (Rosen.Adalog@wanadoo.fr)
Visit Adalog's web site at http://perso.wanadoo.fr/adalog







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

* Re: Subverting 'Access for Sub-programs
  1999-08-03  0:00 ` David C. Hoos, Sr.
@ 1999-08-05  0:00   ` Robert A Duff
  0 siblings, 0 replies; 68+ messages in thread
From: Robert A Duff @ 1999-08-05  0:00 UTC (permalink / raw)


"David C. Hoos, Sr." <david.c.hoos.sr@ada95.com> writes:

> The real problem is that the compiler cannnot know that procedure Main
> will have a lifetime as long as the entire program -- for there is
> nothing that says (at _compile_ time) that procedure Main is the _Main_
> procedure.

The compiler can't know it, because it's not true.  ;-)
Even if the main procedure were marked as such at compile time,
it would still be the case that finalization of library package data
happens after the main procedure is gone, and library-level tasks
keep running for as long as they like after the main procedure is gone.

- Bob
-- 
Change robert to bob to get my real email address.  Sorry.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-04  0:00   ` Jean-Pierre Rosen
  1999-08-04  0:00     ` Brian Rogoff
@ 1999-08-05  0:00     ` Robert A Duff
  1999-08-05  0:00       ` Robert Dewar
  1 sibling, 1 reply; 68+ messages in thread
From: Robert A Duff @ 1999-08-05  0:00 UTC (permalink / raw)


"Jean-Pierre Rosen" <rosen.adalog@wanadoo.fr> writes:

> I understood from a previous message that you didn't like the solution with
> a generic taking a formal procedure.
> It seems however that it would allow you to do precisely what you want.
> You may not "like" generics, but they are inherently safer than access
> values. Actually, in the discussion about downward closures, it was noted
> that all the cases presented could be equally well be dealt with with
> generics, and therefore that it was not worth introducing a risky feature.

There is nothing "risky" about the "limited access-to-subprogram"
feature proposed in an LSN by the design team.  It is equally as safe as
the generic solution.

However, you are correct that the generic solution will work in most
cases.

- Bob
-- 
Change robert to bob to get my real email address.  Sorry.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00       ` Jean-Pierre Rosen
@ 1999-08-05  0:00         ` adam
  1999-08-05  0:00           ` Robert Dewar
  1999-08-05  0:00           ` Subverting 'Access for Sub-programs adam
  1999-08-05  0:00         ` Robert A Duff
  1999-08-06  0:00         ` Brian Rogoff
  2 siblings, 2 replies; 68+ messages in thread
From: adam @ 1999-08-05  0:00 UTC (permalink / raw)


In article <7oc5ih$6mb$1@wanadoo.fr>,
  "Jean-Pierre Rosen" <rosen.adalog@wanadoo.fr> wrote:
>
> OK, I understand your problem better (full examples always help :-)
> Of course, you realize that "Integrator" could store the pointer to
> function to any global variable, possibly resulting later in random
> branches. I think the trade-off in language design was that accessing
> random memory location was bad, but not THAT bad. OTOH, branching to
> random locations was considered really too dangerous. Even if you
> promise not to store the pointer to function to anything global, it
> would be a property of the body, i.e. something that could be changed
> without anybody noticing . . .

Couldn't it be made a property of the access type, instead of a
property of the body?

Was any solution like this considered, when Ada 95 was designed?  The
inability to take an 'ACCESS of an inner subprogram seems like an
obnoxious restriction, a step down from Pascal and Algol, and it seems
like programmers should have an option to remove this restriction at
the expense of adding restrictions elsewhere or perhaps adding runtime
checks.  In fact, I kind of like the idea of allowing a different kind
of subprogram access type declaration such that 3.10.2(28) wouldn't
apply to that type, where the program must check to make sure the
subprogram's ancestors are still on the stack when objects of the type
get dereferenced.  I suspect that in the Integrate case, the compiler
would even be able to tell that this runtime check is unnecessary.

Comments?
                                -- Adam


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00       ` Jean-Pierre Rosen
  1999-08-05  0:00         ` adam
@ 1999-08-05  0:00         ` Robert A Duff
  1999-08-05  0:00           ` Robert Dewar
                             ` (2 more replies)
  1999-08-06  0:00         ` Brian Rogoff
  2 siblings, 3 replies; 68+ messages in thread
From: Robert A Duff @ 1999-08-05  0:00 UTC (permalink / raw)


"Jean-Pierre Rosen" <rosen.adalog@wanadoo.fr> writes:

> OK, I understand your problem better (full examples always help :-)
> Of course, you realize that "Integrator" could store the pointer to function
> to any global variable, possibly resulting later in random branches.

This is not true of either of the proposals the design team proposed.

Your comment is, of course, true of 'Unchecked_Access on subprograms,
but please note that the design team never wanted to allow that.  We
believed that "call backs" and "downward closures" are two separate
features, that each need their own (different) set of restrictions to be
safe.  Call backs can't point to local subprograms, but they can be
copied anywhere you like.  Downward closures can point to local
subprograms, but they can't be copied into global places.  The language
ended up with call backs, but not downward closures.

Your comment is, of course, also true of what we ended up with --
'Unrestricted_Access, which is neither safe nor portable -- it's even
less checked than 'Unchecked_Access.  That's what I meant when I said
"too bad..." in another posting.

- Bob
-- 
Change robert to bob to get my real email address.  Sorry.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00       ` tmoran
  1999-08-05  0:00         ` Aidan Skinner
@ 1999-08-05  0:00         ` Robert Dewar
  1999-08-05  0:00           ` Ray Blaak
  1 sibling, 1 reply; 68+ messages in thread
From: Robert Dewar @ 1999-08-05  0:00 UTC (permalink / raw)


In article <Yq9q3.349$cb1.79221@typhoon-sf.snfc21.pbi.net>,
  tmoran@bix.com wrote:
> > if you could extend the tagged type at a deeper
accessibility level
> It is a real annoyance that tagged types require so much to be
> moved from its natural place out to library level.  IMHO


But it is pretty fundamental and obvious that a tagged type
cannot be extended in a temporary inner scope, no? what are
you suggesting here?

If you are just saying, "I don't like this restriction" fine,
but not particularly constructive :-)


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00         ` adam
@ 1999-08-05  0:00           ` Robert Dewar
  1999-08-05  0:00             ` What is a Display ? (was: Subverting 'Access for Sub-programs) Larry Kilgallen
  1999-08-05  0:00           ` Subverting 'Access for Sub-programs adam
  1 sibling, 1 reply; 68+ messages in thread
From: Robert Dewar @ 1999-08-05  0:00 UTC (permalink / raw)


In article <7occq3$g9v$1@nnrp1.deja.com>,
  adam@irvine.com wrote:
> Was any solution like this considered, when Ada 95 was
> designed?  The inability to take an 'ACCESS of an inner
> subprogram seems like an obnoxious restriction, a step down
> from Pascal and Algol

Remember that Ada 83 was biased towards making the use of
displays efficient (this is in fact why Steelman prohibited
the language from containing subprogram pointers).

Remember that the decision not to allow pointers to nested
procedures in Ada 95 was based on implementation difficulties
with displays. You can second guess this non-technical decision
if you like, but for example, I have heard Aonix folk say that
the current Object Ada would have been significantly impacted
had the decision been made any other way.

Remember that Pascal and Algol semantics definitely IS tricky
for displays, as is well known (nearly all Pascal compilers
use static links).

So it is not clear what you are asking here?


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00         ` adam
  1999-08-05  0:00           ` Robert Dewar
@ 1999-08-05  0:00           ` adam
  1999-08-06  0:00             ` Robert A Duff
  1 sibling, 1 reply; 68+ messages in thread
From: adam @ 1999-08-05  0:00 UTC (permalink / raw)


I wrote:

> Couldn't it be made a property of the access type, instead of a
> property of the body?
>
> Was any solution like this considered, when Ada 95 was designed?  The
> inability to take an 'ACCESS of an inner subprogram seems like an
> obnoxious restriction, a step down from Pascal and Algol, and it seems
> like programmers should have an option to remove this restriction at
> the expense of adding restrictions elsewhere or perhaps adding runtime
> checks.  In fact, I kind of like the idea of allowing a different kind
> of subprogram access type declaration such that 3.10.2(28) wouldn't
> apply to that type, where the program must check to make sure the
> subprogram's ancestors are still on the stack when objects of the type
> get dereferenced.  I suspect that in the Integrate case, the compiler
> would even be able to tell that this runtime check is unnecessary.
>
> Comments?

Actually, posts on this thread that I read after writing the above,
along with some lookup in DejaNews, have mostly answered my question.
However, the discussions I found in DejaNews mentioned proposals to put
restrictions on assignment of these types, but not runtime checks.  Was
anything like this seriously considered?  Would it be simpler to
implement than the other solutions (for implementations that use
displays)?

				-- Adam


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00         ` Robert A Duff
@ 1999-08-05  0:00           ` Robert Dewar
  1999-08-05  0:00           ` Brian Rogoff
  1999-08-05  0:00           ` tmoran
  2 siblings, 0 replies; 68+ messages in thread
From: Robert Dewar @ 1999-08-05  0:00 UTC (permalink / raw)


In article <wcczp06jj39.fsf@world.std.com>,
  Robert A Duff <bobduff@world.std.com> wrote:
> The language ended up with call backs, but not downward
> closures.

Not inappropriate, because call backs were the new feature not
considered in the design of Ada 83. The downward closure issue
has not changed at all from the design of Ada 83, and in fact
it was not clear there was a sufficiently good reason to
embroider in this area.

> Your comment is, of course, also true of what we ended up with
> 'Unrestricted_Access, which is neither safe nor portable --
> it's even less checked than 'Unchecked_Access.

Well that's a bit confused. There is no Unchecked_Access for
subprograms, so I am not quite sure what the comparison would
mean there ...

For other than subprograms, Unrestricted_Access is equivalent to
(though preferable to, since more checked) than taking 'Address
followed by an unchecked conversion. It is to that construct
that Unrestricted_Access should be compared, not
Unchecked_Access.

The fact of the matter is that even with the design teams
proposals, there are still cases where Unrestricted_Access
would be useful for subprograms, since there are cases which
are safe, but the compiler cannot tell they are safe.

To me the dangling data references of Unchecked_Access are not
particularly better than the dangling subprogram pointers of
Unrestricted_Access. The consequence of either is possible
data corruption (in the former case, from a bad address, in
the latter case from a bad static link).

Note that Unrestricted_Access applied to an inner procedure with
no non-local references is in fact entirely safe (such nested
procedures are not at all uncommon, they are used in cases where
you want to restrict the visibility of a local nested
subprogram).


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00         ` Robert A Duff
  1999-08-05  0:00           ` Robert Dewar
  1999-08-05  0:00           ` Brian Rogoff
@ 1999-08-05  0:00           ` tmoran
  1999-08-06  0:00             ` Robert A Duff
  2 siblings, 1 reply; 68+ messages in thread
From: tmoran @ 1999-08-05  0:00 UTC (permalink / raw)


> ... true of 'Unchecked_Access on subprograms,
>but please note that the design team never wanted to allow that.
  Have I missed a message where the safe method the design team
contemplated was described?




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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00     ` Robert A Duff
@ 1999-08-05  0:00       ` Robert Dewar
  1999-08-05  0:00         ` Brian Rogoff
  0 siblings, 1 reply; 68+ messages in thread
From: Robert Dewar @ 1999-08-05  0:00 UTC (permalink / raw)


In article <wccoggm9w94.fsf@world.std.com>,
  Robert A Duff <bobduff@world.std.com> wrote:
> There is nothing "risky" about the "limited
> access-to-subprogram" feature proposed in an LSN by the design
> team.  It is equally as safe as
> the generic solution.


Yes, and also very restrictive. Many of the cases in which I
have used Unrestricted_Access would not be handled by the
limited access-to-subprogram capability in any case.


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* What is a Display ? (was: Subverting 'Access for Sub-programs)
  1999-08-05  0:00           ` Robert Dewar
@ 1999-08-05  0:00             ` Larry Kilgallen
  1999-08-05  0:00               ` Hyman Rosen
  1999-08-06  0:00               ` Robert Dewar
  0 siblings, 2 replies; 68+ messages in thread
From: Larry Kilgallen @ 1999-08-05  0:00 UTC (permalink / raw)


... in the context of the following comments:

In article <7ocra4$s8o$1@nnrp1.deja.com>, Robert Dewar <robert_dewar@my-deja.com> writes:

> Remember that Ada 83 was biased towards making the use of
> displays efficient (this is in fact why Steelman prohibited
> the language from containing subprogram pointers).
> 
> Remember that the decision not to allow pointers to nested
> procedures in Ada 95 was based on implementation difficulties
> with displays. You can second guess this non-technical decision
> if you like, but for example, I have heard Aonix folk say that
> the current Object Ada would have been significantly impacted
> had the decision been made any other way.
> 
> Remember that Pascal and Algol semantics definitely IS tricky
> for displays, as is well known (nearly all Pascal compilers
> use static links).




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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00         ` Robert A Duff
  1999-08-05  0:00           ` Robert Dewar
@ 1999-08-05  0:00           ` Brian Rogoff
  1999-08-06  0:00             ` Robert Dewar
  1999-08-05  0:00           ` tmoran
  2 siblings, 1 reply; 68+ messages in thread
From: Brian Rogoff @ 1999-08-05  0:00 UTC (permalink / raw)


On Thu, 5 Aug 1999, Robert A Duff wrote:
> "Jean-Pierre Rosen" <rosen.adalog@wanadoo.fr> writes:
> 
> > OK, I understand your problem better (full examples always help :-)
> > Of course, you realize that "Integrator" could store the pointer to function
> > to any global variable, possibly resulting later in random branches.
> 
> This is not true of either of the proposals the design team proposed.

That is true, and in the example I posted I used 'Unrestricted_Access is
the most portable solution. Your limited access to subprogram would have
worked fine, or even just Pascal style subprogram arguments (meaning, why 
confuse access types and subprogram types?).  

Your proposal to allow tagged limited types to be extended in nested
scopes was also pretty cool, though I'd like something like that in
addition to downward funargs. But downward funargs alone are way
useful; given the ability to use downward funargs safely I'd be more
likely to use funargs to parameterize the behavior of a primitive
subprogram of a tagged type than a nested extension.
 
> Your comment is, of course, true of 'Unchecked_Access on subprograms,
> but please note that the design team never wanted to allow that.  We
> believed that "call backs" and "downward closures" are two separate
> features, that each need their own (different) set of restrictions to be
> safe.  Call backs can't point to local subprograms, but they can be
> copied anywhere you like.  Downward closures can point to local
> subprograms, but they can't be copied into global places.  The language
> ended up with call backs, but not downward closures.
>
> Your comment is, of course, also true of what we ended up with --
> 'Unrestricted_Access, which is neither safe nor portable -- it's even
> less checked than 'Unchecked_Access.  That's what I meant when I said
> "too bad..." in another posting.

I think that the use of the feature is justified. If people don't think
the omission of downward funargs is a flaw, it will never get fixed. 
Unrestricted_Access is a way to get the hint across. Modify GNAT to use 
your safe proposal and I'll switch :-)

It was probably the right choice at the time (1990-1995) to exclude
downward funargs, and Robert Dewar's statement about the pain some
implementor's would have suffered seems reasonable enough. It won't seem 
reasonable much longer though.

-- Brian






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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00       ` Robert Dewar
@ 1999-08-05  0:00         ` Brian Rogoff
  0 siblings, 0 replies; 68+ messages in thread
From: Brian Rogoff @ 1999-08-05  0:00 UTC (permalink / raw)


On Thu, 5 Aug 1999, Robert Dewar wrote:
> In article <wccoggm9w94.fsf@world.std.com>,
>   Robert A Duff <bobduff@world.std.com> wrote:
> > There is nothing "risky" about the "limited
> > access-to-subprogram" feature proposed in an LSN by the design
> > team.  It is equally as safe as
> > the generic solution.
> 
> 
> Yes, and also very restrictive. Many of the cases in which I
> have used Unrestricted_Access would not be handled by the
> limited access-to-subprogram capability in any case.

Pointers to some illustrative examples? GNAT sources work. 

Do you think in the cases that you needed subprogram parameters that 
the majority of cases wouldn't be handled by the current feature set 
plus Bod Duff's limited acces to subprogram types? 

Its still useful, even if you need an unsafe feature, to be able to handle 
most cases safely.

-- Brian





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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00         ` Robert Dewar
@ 1999-08-05  0:00           ` Ray Blaak
  1999-08-06  0:00             ` Jean-Pierre Rosen
  1999-08-06  0:00             ` Robert Dewar
  0 siblings, 2 replies; 68+ messages in thread
From: Ray Blaak @ 1999-08-05  0:00 UTC (permalink / raw)


Robert Dewar <robert_dewar@my-deja.com> writes:
> But it is pretty fundamental and obvious that a tagged type
> cannot be extended in a temporary inner scope, no? 

It is not fundamental and obvious to me. Perhaps you could explain.

I am aware of implementation concerns with allowing such a thing, but the
restriction seems is an exception to the generality of declaring Ada
constructs that is usually allowed.

One can declare types, exceptions, variables, and routines anywhere, except for
tagged types. This restriction prevents a completely localized programming
style when doing OO stuff.

Is the issue downward closures again? I would really like to see them
allowed. Things like localized iterators could be done in a natural way. 

The current practice of knowing that some things have to be defined at the
library level is not something that is obvious when reading sources, and is
something that just seems to be part of the Ada lore.

-- 
Cheers,                                        The Rhythm is around me,
                                               The Rhythm has control.
Ray Blaak                                      The Rhythm is inside me,
blaak@infomatch.com                            The Rhythm has my soul.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00       ` tmoran
@ 1999-08-05  0:00         ` Aidan Skinner
  1999-08-05  0:00         ` Robert Dewar
  1 sibling, 0 replies; 68+ messages in thread
From: Aidan Skinner @ 1999-08-05  0:00 UTC (permalink / raw)


On Thu, 05 Aug 1999 05:38:00 GMT, tmoran@bix.com <tmoran@bix.com> wrote:

>It is a real annoyance that tagged types require so much to be
>moved from its natural place out to library level.  IMHO

I thought this as well, but then I realised how much this encourages
reuse. If you stick all your functionality into librarys in the first
place it makes it much more likely that you'll end up reusing the
code.

Plus it makes it easier to seperate user interface from
implementation.

YMMV.

- Aidan
-- 
Gimme money, gimme sex, gimme UNIX and root access.
http://www.skinner.demon.co.uk/aidan/




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

* Re: Subverting 'Access for Sub-programs
  1999-08-04  0:00     ` Brian Rogoff
@ 1999-08-05  0:00       ` tmoran
  1999-08-05  0:00         ` Aidan Skinner
  1999-08-05  0:00         ` Robert Dewar
  0 siblings, 2 replies; 68+ messages in thread
From: tmoran @ 1999-08-05  0:00 UTC (permalink / raw)


> if you could extend the tagged type at a deeper accessibility level
It is a real annoyance that tagged types require so much to be
moved from its natural place out to library level.  IMHO




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

* Re: Subverting 'Access for Sub-programs
  1999-08-04  0:00   ` Robert A Duff
  1999-08-04  0:00     ` Brian Rogoff
@ 1999-08-05  0:00     ` Anton Gibbs
  1 sibling, 0 replies; 68+ messages in thread
From: Anton Gibbs @ 1999-08-05  0:00 UTC (permalink / raw)


Robert A Duff wrote:

> There is no good solution to this problem: no solution that is portable,
> concise, reentrant, &c.
> 
> One thing you can do is declare a tagged type, and use an extension as
> the environment of the procedure you want to pass -- then instead of
> passing a procedure as a parameter, pass an object of the class-wide
> type.

Er, thanks Bob. Maybe I will just revert to good old generics a la
Ada83.

Thanks for your help.

Best -- Anton.

-- 
Civil Air Traffic Management Group
Defence Evaluation and Research Agency
Bedford, UK

"The Information contained in this E-Mail and any 
subsequent correspondence is private and is intended
solely for the intended recipient(s).  For those
other than the intended recipient any disclosure,
copying, distribution, or any action taken or 
omitted to be taken in reliance on such information
is prohibited and may be unlawful."




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

* Re: Subverting 'Access for Sub-programs
  1999-08-04  0:00     ` Brian Rogoff
@ 1999-08-05  0:00       ` Jean-Pierre Rosen
  1999-08-05  0:00         ` adam
                           ` (2 more replies)
  0 siblings, 3 replies; 68+ messages in thread
From: Jean-Pierre Rosen @ 1999-08-05  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 2532 bytes --]


Brian Rogoff <bpr@shell5.ba.best.com> a �crit dans le message :
Pine.BSF.4.10.9908042041540.29130-100000@shell5.ba.best.com...
On Wed, 4 Aug 1999, Jean-Pierre Rosen wrote:
> [snip]
>> I understood from a previous message that you didn't like the solution
with
>> a generic taking a formal procedure.
>> It seems however that it would allow you to do precisely what you want.
>> You may not "like" generics, but they are inherently safer than access
>> values. Actually, in the discussion about downward closures, it was noted
>> that all the cases presented could be equally well be dealt with with
>> generics, and therefore that it was not worth introducing a risky
feature.

>Not true for any reasonable value of "equally well". For instance, in one
>of those ancient postings of a few years ago on this very topic Richard
>O'Keefe presented the example of making a two dimensional integrator from
>a one dimensional one. The Ada version with generics depended on the name
>of the one dimensional integratoir, and so it was parameterized by that
>particular integrator. The downward closure one was free to range over all
>one dimensional integrators. I'll append the code, if you can come up with
>a perspicuous generic version that doesn't depend on the one dimensional
>code I'll be more convinced.
[code snipped for brievity]
OK, I understand your problem better (full examples always help :-)
Of course, you realize that "Integrator" could store the pointer to function
to any global variable, possibly resulting later in random branches.
I think the trade-off in language design was that accessing random memory
location was bad, but not THAT bad. OTOH, branching to random locations was
considered really too dangerous. Even if you promise not to store the
pointer to function to anything global, it would be a property of the body,
i.e. something that could be changed without anybody noticing, not even
requiring recompilation of users.
So take it as a trade-off between security and usability. But in the real
world (i.e. not academic exercise), is it so important to dynamically choose
the 1D integrator ? As you note, if the 1D integrator is fixed, there is an
easy solution with generics.

>I think its also true that in the typical implementation of generics there
>will be a code size problem too.
RR software has full generics sharing.

--
---------------------------------------------------------
           J-P. Rosen (Rosen.Adalog@wanadoo.fr)
Visit Adalog's web site at http://perso.wanadoo.fr/adalog







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

* Re: Subverting 'Access for Sub-programs
  1999-08-04  0:00 ` Anton Gibbs
  1999-08-04  0:00   ` Robert A Duff
  1999-08-04  0:00   ` Jean-Pierre Rosen
@ 1999-08-05  0:00   ` Steve Quinlan
  2 siblings, 0 replies; 68+ messages in thread
From: Steve Quinlan @ 1999-08-05  0:00 UTC (permalink / raw)


I don't think I saw anyone suggest that an integer parameter could be added
to Database.Perform. If, when you call that routine, you always know the the
value which you wish passed in to the action_type subprogram, then you're
fine. Then Perform has both the subprogram to call and the value needed to
call it as parameters.





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

* Re: What is a Display ? (was: Subverting 'Access for Sub-programs)
  1999-08-05  0:00             ` What is a Display ? (was: Subverting 'Access for Sub-programs) Larry Kilgallen
@ 1999-08-05  0:00               ` Hyman Rosen
  1999-08-06  0:00                 ` Robert Dewar
  1999-08-06  0:00               ` Robert Dewar
  1 sibling, 1 reply; 68+ messages in thread
From: Hyman Rosen @ 1999-08-05  0:00 UTC (permalink / raw)


kilgallen@eisner.decus.org (Larry Kilgallen) writes:
> What is a Display ?

A display is an array of frame pointers. It is as large as the static
nesting depth of the most deeply nested procedure of the program. Each
frame pointer in the display points to the stack frame of the most
recently called procedure at the static nesting depth of its
index. Its use allows local variables in enclosing procedures to be
accessed with a single extra indirection, as opposed to static links
which require chaining backwards for each level. Since such access
tends to be rare, static links are probably better.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00       ` Jean-Pierre Rosen
  1999-08-05  0:00         ` adam
  1999-08-05  0:00         ` Robert A Duff
@ 1999-08-06  0:00         ` Brian Rogoff
  1999-08-07  0:00           ` Gautier
  2 siblings, 1 reply; 68+ messages in thread
From: Brian Rogoff @ 1999-08-06  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: TEXT/PLAIN; charset=X-UNKNOWN, Size: 3510 bytes --]

On Thu, 5 Aug 1999, Jean-Pierre Rosen wrote:
> Brian Rogoff <bpr@shell5.ba.best.com> a écrit dans le message :
> Pine.BSF.4.10.9908042041540.29130-100000@shell5.ba.best.com...
> On Wed, 4 Aug 1999, Jean-Pierre Rosen wrote:
> > [snip]
> >> I understood from a previous message that you didn't like the solution
> with
> >> a generic taking a formal procedure.
> >> It seems however that it would allow you to do precisely what you want.
> >> You may not "like" generics, but they are inherently safer than access
> >> values. Actually, in the discussion about downward closures, it was noted
> >> that all the cases presented could be equally well be dealt with with
> >> generics, and therefore that it was not worth introducing a risky
> feature.
> 
> >Not true for any reasonable value of "equally well". For instance, in one
> >of those ancient postings of a few years ago on this very topic Richard
> >O'Keefe presented the example of making a two dimensional integrator from
> >a one dimensional one. The Ada version with generics depended on the name
> >of the one dimensional integratoir, and so it was parameterized by that
> >particular integrator. The downward closure one was free to range over all
> >one dimensional integrators. I'll append the code, if you can come up with
> >a perspicuous generic version that doesn't depend on the one dimensional
> >code I'll be more convinced.
> [code snipped for brievity]
> OK, I understand your problem better (full examples always help :-)
> Of course, you realize that "Integrator" could store the pointer to function
> to any global variable, possibly resulting later in random branches.

Yes, I only used 'Unrestricted_Access because that is the only workable
solution in any Ada I know of. In Pascal, you wouldn't use function
pointers at all so the safety issue does not arise; really the issue is 
what kind of support for downward closures for Ada provide. A safe
solution to this problem, like Bob Duff's limited access to subprogram, 
was rejected but there are other possibilities too.

So, in short, the safety issue is orthogonal, mostly a detail of how you 
provide this capability.

> I think the trade-off in language design was that accessing random memory
> location was bad, but not THAT bad. OTOH, branching to random locations was
> considered really too dangerous. Even if you promise not to store the
> pointer to function to anything global, it would be a property of the body,
> i.e. something that could be changed without anybody noticing, not even
> requiring recompilation of users.
> So take it as a trade-off between security and usability. But in the real
> world (i.e. not academic exercise), is it so important to dynamically choose
> the 1D integrator ? As you note, if the 1D integrator is fixed, there is an
> easy solution with generics.

Yes, I think in the real world the decoupling provided by real downward
closures over the generic approach is better because it allows more
abstract, readable, and reusable code to be written. Whether it is worth 
it in the context of a future version of Ada is a more complicated
question to answer. My "real world" desire for this feature comes up
frequently with mapping functions. I also wanted it when I was writing a
backtracking parser, but the generic workaround is not as bad there. 

> RR software has full generics sharing.

Anyone do sometimes share / sometimes expand? I'm curious.

-- Brian






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

* Re: What is a Display ? (was: Subverting 'Access for Sub-programs)
  1999-08-05  0:00             ` What is a Display ? (was: Subverting 'Access for Sub-programs) Larry Kilgallen
  1999-08-05  0:00               ` Hyman Rosen
@ 1999-08-06  0:00               ` Robert Dewar
  1 sibling, 0 replies; 68+ messages in thread
From: Robert Dewar @ 1999-08-06  0:00 UTC (permalink / raw)


In article <1999Aug5.175752.1@eisner>,
  Kilgallen@eisner.decus.org.nospam wrote:
> ... in the context of the following comments:

A display is a standard mechanism for uplevel referencing.
Basically it is a table of addresses of statically enclosing
frames. FOr details see any compiler book, e.g. the dragon
book.

The common alternative is a static link, which is simply
a pointer to the nearest statically enclosing frame, then
you follow the links to get to higher levels


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: What is a Display ? (was: Subverting 'Access for Sub-programs)
  1999-08-05  0:00               ` Hyman Rosen
@ 1999-08-06  0:00                 ` Robert Dewar
  0 siblings, 0 replies; 68+ messages in thread
From: Robert Dewar @ 1999-08-06  0:00 UTC (permalink / raw)


In article <t7907pbwwc.fsf@calumny.jyacc.com>,
  Hyman Rosen <hymie@prolifics.com> wrote:

> kilgallen@eisner.decus.org (Larry Kilgallen) writes:
> > What is a Display ?
>
> Since such access
> tends to be rare, static links are probably better.

Well this is arguable, and in my experience it is not unusual
for Ada programs to violate this rule.

But more to the point, consider the following categories:

1. Calls to global procedures not containing nested procedures
2. Calls to global procedures containing nested procedures
3. Calls to nested procedures not containing nested procedures
4. Calls to nested procedures containing nested procedures

For static links, 1,2 involve no overhead on the call, but 3,4
do require the overhead of setting up the static link.

For displays 1,3 involve no overhead on the call, but 2,4 do
require the overhead of updating the display.

Now obviously if you have no nested procedures, then you are in
case 1 all the time, and neither approach causes any overhead.

If you have nested procedures, the question is which is better.
I think it is clear that displays come off better -- why? Well
for displays we only pay overhead on a call to a procedure that
contains nested procedures, but in such cases, almost surely
there will be significantly more calls to leaves (i.e. to the
nested procedures), than to the procedure containing them. But
in the static link case, you pay for calls to ALL non-global
subprograms.

This analysis does not however include the impact of general
procedure pointers without the ADa 95 restrictions. In that
case, you would find displays so much less efficient for the
case of calling subprograms via an access pointer, that you
would almost surely choose static links.

With the rules of Ada 95, which are carefully designed so that
this extra impact on display implementations does not occur, it
is probably the case that a per-task display represents the most
efficient handling of non-local references.

Consider for example, a not uncommon case, where you have a
large procedure that contains a large number of nested
procedures (e.g. look at Analyze_Attribute in the GNAT sources).

There is one call to Analyze_Attribute (that would involve call
overhead for the display case, but not for the static link case)

But then when the analysis call makes a sequence of calls to
the nested procedures, which often call one another, the display
approach would have zero overhead for all such calls, whereas
the static link case would have to update the link on each call.

Robert Dewar


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00           ` Ray Blaak
  1999-08-06  0:00             ` Jean-Pierre Rosen
@ 1999-08-06  0:00             ` Robert Dewar
  1999-08-06  0:00               ` Robert A Duff
  1 sibling, 1 reply; 68+ messages in thread
From: Robert Dewar @ 1999-08-06  0:00 UTC (permalink / raw)


In article <m3iu6tjw2d.fsf@vault83.infomatch.bc.ca>,
  Ray Blaak <blaak@infomatch.com> wrote:
> It is not fundamental and obvious to me. Perhaps you could
> explain.

Well this has been dealt with in length in previous threads,
so it is not appropriate to repeat it, but briefly, an extension
of a tagged type with new overriding primitives clearly
generates the possibility of dispatching to these new
primitives. If you allow extension in a smaller scope, you
can obviously generate dangling pointers for these methods,
using class variables whose value is the inner derived type.
It would thus be unsafe to allow this extension.
>
> I am aware of implementation concerns with allowing such a
> thing, but the restriction seems is an exception to the
> generality of declaring Ada constructs that is usually
> allowed.

It is not an implementation concern, it is trivial to allow
this in an implementation, it is a concern with safety of the
code and avoiding dangling pointers.

Pointers are in general a menace, they are the "gotos" of
data structures. Ada admits them into the language, but only
under the strict rule that if you do not use unchecked features,
then you can never generate a dangling pointer. Dangling
pointers are very dangerous when dealing with nested procedures
because they can lead to undetected and subtle data corruption.

> The current practice of knowing that some things have to be
> defined at the library level is not something that is obvious
> when reading sources, and is something that just seems to be
> part of the Ada lore.

I see no reason to expect that you could learn the rules of
a language simply by reading code. This rule is in fact very
clearly stated in the RM 3.9.1:

3   The parent type of a record extension shall not be a
    class-wide type.  If the parent type is nonlimited, then
    each of the components of the record_extension_part shall
    be nonlimited. The accessibility level (see 3.10.2) of a
    record extension shall not be statically deeper than that
    of its parent type.  In addition to the places where
    Legality Rules normally apply (see 12.3), these rules apply
    also in the private part of an instance of a generic unit.

Seems clear enough, hardly part of the "lore" of Ada unless you
include the rules of the language in the standard. And if you
do, all I can say is where else do you expect to find the rules
of writing Ada except in the book of rules :-)


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00           ` Brian Rogoff
@ 1999-08-06  0:00             ` Robert Dewar
  1999-08-09  0:00               ` Tucker Taft
  0 siblings, 1 reply; 68+ messages in thread
From: Robert Dewar @ 1999-08-06  0:00 UTC (permalink / raw)


In article
<Pine.BSF.4.10.9908052144260.14625-100000@shell5.ba.best.com>,
> It was probably the right choice at the time (1990-1995) to
> exclude downward funargs, and Robert Dewar's statement about
> the pain some implementor's would have suffered seems
> reasonable enough. It won't seem reasonable much longer
> though.

Indeed! And probably it is time for the ARG to address this
issue, and decide on an accepted language extension in this
area.

I am not sure that Unrestricted_Access (as defined by GNAT
for procedures) should be part of that proposal. Most certainly
you also want a "safe" version similar to what was proposed in
earlier mapping documents (the limited access to subprogram
feature).

Note that Unrestricted_Access in GNAT has three quite different
meanings:

1. For objects other than slices and unconstrained array types,
it provides a considerably nicer diction than taking the
'Address and converting the address to the required
access type by using unchecked conversion (a common Ada 83
diction). Since it adds no expressive capability, and is
obviously no implementation burden, this usage seems one that
would usefully be included in all Ada compilers.

2. For slice objects and unconstrained array type pointers, GNAT
permits capturing pointers to slices that "work", although there
are fairly subtle scoping restrictions. This very much depends
on the internal approach that GNAT uses for such pointers (the
so called "fat" pointers). It is not a usage that should be
encouraged, and certainly not one that should be standardized
at this time, since it would have far reaching implementation
impact in compilers other than GNAT. So this use of
Unrestricted_Access should definitely be considered to be
GNAT dependent (it can of course be VERY useful in some
situations, e.g. we have found it very useful for some work in
automatic translation of COBOL code).

3. For subprograms, Unrestricted_Access provides a general
mechanism corresponding really to what would more naturally
be called Unchecked_Access, and to me the natural extension
in the language would be to use Unchecked_Access for the
purpose. I don't see any big semantic problem here. Pointers
generated by the use of UA are the same as any other pointers
generated by use of UA, namely you had better not use them
when the corresponding referenced gizmo (be it an object as
now allowed in the language, or a subprogram, as now forbidden)
goes out of scope. The implementation impact is no worse than
will be required for general downward funargs, so if you buy
the latter, why not allow Unchecked_Access on subprograms as
the natural extension.

I think that even if you implement the "safe" downward funargs
features, you will still feel a need for UA on subprograms. The
situations in which you need this are exactly similar to those
which cause you to use UA for objects, e.g. you want to park
pointers in some global structures, for later use, and you
happen to know that your logic is such that they will not be
used after the referenced gizmo has gone out of scope.

For example, I have a general library level procedure that does
callbacks, and expects to be passed a record containing the
stuff necessary for the callback processing, including an
access-to-subprogram value. Currently I can't use a nested
subprogram for that purpose which is annoying, and the "safe"
proposal still won't allow it.

Robert Dewar


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00           ` tmoran
@ 1999-08-06  0:00             ` Robert A Duff
  0 siblings, 0 replies; 68+ messages in thread
From: Robert A Duff @ 1999-08-06  0:00 UTC (permalink / raw)


tmoran@bix.com writes:

> > ... true of 'Unchecked_Access on subprograms,
> >but please note that the design team never wanted to allow that.
>   Have I missed a message where the safe method the design team
> contemplated was described?

Not a *recent* message, but it's been discussed before.
Here's the language study note that folks have been
referring to.  Note that I wrote this some years ago,
and I don't necessarily still agree with myself on every
detail.  ;-)

There were actually *two* safe methods proposed -- one involving
compile-time checks and one involving run-time checks.  I prefer the
compile-time-checked version.  Robert Dewar is quite correct that
there are things that 'Unrestricted_Access can do that the proposals
below can't.

!topic LSN on General Access Types
!key LSN-1083 on General Access Types
!reference RM9X-3.10.2;4.0
!reference RM9X-3.10.2(16);4.0
!reference AARM-12.3(12.p,12.q);4.0
!reference LSN-1042 on Accessibility Checks in Generics
!from Bob Duff $Date: 94/02/15 15:17:44 $ $Revision: 1.5 $
!discussion

Two issues related to access types and the accessibility rules came
up again at the recent DR/XRG meeting in the UK:

    - The rules prevent "downward closures".

    - The rules are applied in an assume-the-worst manner in generic
      bodies.

These issues keep coming up, because they represent clearly-desirable
functionality, but with a substantial implementation cost (at least for
some implementations).  It is difficult to make the trade-off.  We
recommend not supporting downward closures, but solving the generic
problem by going over to run-time accessibility checks in generics.
Below, we discuss the issues, and the reasons for our recommendation.

LSN-1042, published in October, 1992, discusses in general the
relationship between accessibility checks and the generic contract
model.

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

Downward Closures:

Ada's access-to-subprogram types represent assignable subprogram
values.  They support the ability to create data structures
containing the identities of subprograms.  They support callbacks,
where one software component declares a subprogram and hands its
identity to another software component, which can then "call back"
the first software component at a later time.

These types do not support downward closures, where the identity of a
more nested subprogram can be passed to a less nested subprogram.
Downward closures can be used, for example, to implement iterators,
like this:

    package P is
        type Integer_Set is private;
        ... -- various operations
        type Integer_Action is access procedure(I: Integer);
        procedure Iterate(S: Integer_Set; Action: Integer_Action);
            -- Call Action on each member of S.
    end P;

    function Count(S: Integer_Set) return Natural is
        Result: Natural := 0;
        procedure Increment(I: Integer) is
        begin
            Result := Result + 1;
        end Increment;
    begin
        Iterate(S, Increment'Access); -- Illegal!
        return Result;
    end Count;

Increment'Access above is illegal, because Increment is more nested
than type Integer_Action.  It would be bad to have to make Increment
global, because that would require making the variable Result global.
It is a bad idea to force the use of global variables in a language
that has tasks -- in this example, Count would not be reentrant if
Result were global.

Note that this situation is typical of iterators and similar things
-- in typical use, the action passed to an iterator will often need
visibility upon a variable declared in the caller of the iterator, in
order to accumulate some sort of result.

The reason for the restriction is that access-to-subprogram types
allow assignment.  At the point where Iterate is called, we don't
know if the body of Iterate is going to save the access value in a
global variable.  We disallow passing the nested Increment procedure
because Iterate *might* save a pointer to it, and call it later,
after Increment (and the variable Result) no longer exist.

Pascal supports downward closures, but it does not support Ada's
callback style, because the identity of a subprogram being passed as
a parameter cannot be copied.  Modula-2 supports the callback style,
but not the downward closure style.  Languages like Lisp support a
much more general form of closure, which is not of interest to us,
since it requires "stack frames" to be heap allocated -- "heap
frames", really, in the general case.  C supports the callback style,
but since there are no nested functions, the question of downward
closures does not arise.  There are no tasks, either, in C, so making
variables global (or C's "static") does not cause as much trouble as
in Ada.  (Supporting threads in C presents some interesting
problems!)

Implementation Issues: In a language (like Ada) with nested
subprograms, each subprogram needs some way to access its environment
-- that is, the variables declared outside it.  There are two common
methods for representing this environment: static links, and
displays.  Most Ada compilers use static links, but some use
displays.  One key difference between the two methods is that static
links have a compile-time-known size (32 bits, on a typical machine),
whereas the size of a display depends on the maximum nesting depth
throughout the partition.

In an implementation with static links, an access-to-subprogram value
is generally represented as a pair of addresses -- the address of the
subprogram's code, and the static link.  However, given the current
Ada 9X rules, an access-to-subprogram type that is declared at
library level does not need the static link -- it can be represented
as just a code address.  This is nice, because it is efficient, and
it allows the representation to easily match C's typical
representation of function pointers.  Access-to-subprogram types
declared one level deeper than library level can also be represented
as just a code address.  However, two or more levels deeper requires
the static link.

In an implementation with displays, given the current rules, an
access-to-subprogram value can be represented as just a code address
-- it is not necessary to attach a display to each access value.
This also has the nice interoperability-with-C property.

It has been suggested that downward closures be supported by allowing
the Unchecked_Access attribute on subprograms.  (It is currently
allowed only on objects.)  The semantics would presumably be that the
access value returned is valid (the designated subprogram can be
called) so long as the designated subprogram (and it's containing
stack frame) still exist.  If it doesn't exist, a dereference would
be erroneous.  We do not recommend this method for these reasons:

    - It would be unsafe -- it is uncomfortable to introduce
      erroneousness to a high-level feature like downward closures.

    - It would require every access-to-subprogram value to carry a
      static link or display, because the nesting level of the
      designated subprogram would no longer be restricted at
      compile time.  This would break the interoperability-with-C
      property, and would be less efficient.  (One could imagine
      an implementation using a different representation when the
      Convention is C, but that adds complexity, and doesn't solve
      the efficiency problem in the Ada-only case.)

There are two ways to support downward closures that we would
recommend, if downward closures are to be supported.  Both ways
recognize the fact that downward closures really need a separate
feature from the callback style of access-to-subprograms:

    - Limited access-to-subprogram types.

    - Access-to-subprogram parameters.

Limited access types were in an earlier version of Ada 9X.  Since
they would be limited, assignment would be disallowed, so
downward-closure-style parameter passing could be allowed, and would
be safe.  The compiler would implement limited access-to-subprogram
types with a static link or display.  Non-limited ones would retain
the interoperability-with-C property.  The syntax would be something
like this:

    type Integer_Action is limited access procedure(I: Integer);
                        -- ^^^^^^^
    procedure Iterate(S: Integer_Set; Action: Integer_Action);
        -- Call Action on each member of S.

Type conversion from limited to non-limited would be illegal.

Access-to-subprogram parameters would be an extension to access
parameters (not to be confused with parameters of a named access
type).  The syntax would be something like this:

    procedure Iterate(S: Integer_Set;
                      Action: access procedure(I: Integer));
        -- Call Action on each member of S.

This is quite similar to the syntax used in Pascal.  As for any access
parameter, the access type would be anonymous.  Parameter type matching
would be based on the designated profile.  Access parameters already use
run-time accessibility checks -- this new kind would do likewise.  Thus,
assignment would be allowed, but the accessibility checks would prevent
dangling pointers.  In our iterator example, if Iterate were to try to
copy Action to a global variable (during the call to Iterate from
Count), then Constraint_Error would be raised, because Count.Increment
is too deeply nested.  The value of an access-to-subprogram parameter
would need to have a static link or display.  Library-level access types
could retain the interoperability-with-C property.

Of the two workable methods outlined above, the access-to-subprogram
parameters method would be somewhat simpler in Reference Manual
terms, because it would be able to piggyback on the existing access
parameters feature for its rules and semantics.  The implementation
complexity seems equivalent.  Efficiency of the limited access types
method would be slightly better, because it would not be necessary to
pass in information needed for the run-time accessibility checks.
Limited access types would be the first elementary limited types;
we would have to reword the parameter passing rules to avoid a
contradictory requirement to pass by copy and by reference.  (It
doesn't really matter which is done, actually.)

For implementations with static links, the implementation of either
method is straightforward.  Such implementations already need to
include a static link in at least some access-to-subprogram values,
and the downward-closure ones would be the same.

However, for implementations with displays, either method is an
implementation burden, because:

    - The current rules do not require carrying the display
      with the access-to-subprogram value, whereas the new
      rules would.

    - The size of the display is not easily known at compile time.
      It's size can be calculated at run time, or a maximum possible
      size can be known if there is a restriction on nesting depth.
      Either way, managing the passing of the unknown size display
      causes complexity.  It is certainly *possible* to implement:
      I know of at least one Pascal compiler that used displays,
      and implemented downward closures.  Gnu C supports nesting
      of functions as an extension, and supports pointers to them.
      And Ada has other features that require the management of
      unknown-sized data structures.  Nonetheless, the implementation
      is not trivial.

It should also be noted that an implementation with displays would be
less efficient than one with static links, because an indirect call
would require copying the entire display.  It's not that big of a
deal, however -- it just means copying several words of memory, and
there would be no *distributed* overhead.

Note also that there are workarounds: Subprograms can be passed as
generic formal parameters, so an iterator can often be implemented as
a generic formal parameter.  However, that prevents recursion, and is
more verbose.  A closure can also be represented as an
access-to-class-wide value.  In the iterator example, whatever state
is needed by the Action procedure would be encapsulated in a type
extension.  However, this method is even more verbose.

One possibility would be to not support downward closures directly as
access-to-subprogram types, but to make the workaround a bit easier.  In
particular, we could allow limited tagged types to be extended in a more
nested place than the parent type.  (The accessibility rule would remain
as is for non-limited type extensions.)  Instead, a rule would be needed
for allocators, similar to the current rule for types with access
discriminants.  This relaxation is possible for limited types, because
they have no assignment, and hence cannot be copied to a place where the
object lives longer than its type.  This would allow the following:

    package P is
        type Integer_Set is private;
        ... -- various operations
        type Closure is tagged limited null record;
        procedure Action(C: Closure; I Integer);
        procedure Iterate(S: Integer_Set; C: Closure);
            -- Call Do_It(Action, M) for each member M of S.
    end P;

    function Count(S: Integer_Set) return Natural is
        type My_Closure_Type is new Closure with null record; -- Illegal!
        Result: Natural := 0;
        procedure Action(C: Closure; I: Integer) is
        begin
            Result := Result + 1;
        end Action;
        My_Closure: My_Closure_Type;
    begin
        Iterate(S, My_Closure);
        return Result;
    end Count;

The above is less verbose than the current workaround, and has the
advantage that My_Closure_Type can be declared where it arguably belongs
-- inside Count.

The implementation could store the static link or display in each object
of a limited type extension that was declared at a more-nested level
than its parent.  Code would be added to each potentially primitive
subprogram of such a type, to move the static link or display from the
parameter object to its proper location.  Note that no change to the
call sites is necessary.  Nonetheless, there is some implementation
burden, because extra compiler work is needed for declaring these
objects, and in the bodies of the potentially primitive subprograms.

(The reason I say "potentially" primitive is that because of renaming,
we don't know in general while compiling a given subprogram that it will
be primitive.  Potentially primitive subprograms are essentially the
ones declared at the same nesting level, and that take a parameter of
the type.)

We (reluctantly) recommend not supporting downward closures, because:

    - An implementation burden exists for display-based implementations.

    - Workarounds exist.

    - It seems like too big a change to make to the language at this
      late date.

I say "reluctantly" recommend, because it is clear to me that the
functionality is desirable, and if we were designing Ada 9X from
scratch, we would support downward closures.

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

Generic Bodies:

Currently, accessibility rules are checked in generic bodies in an
assume-the-worst manner (see 3.10.2(16) and 12.3(12.p,12.q)).  This
means that such rules are checked assuming the instantiation will be
more nested than the generic unit.  This is unfortunate, since most
of the time, the instance will be at the same nesting level as the
generic unit; the rules are therefore more pessimistic than is
usually necessary.

In many cases, it is possible to work around the problem by moving
something from the generic body up to the private part.  For example,
suppose P is a subprogram declared in a generic body, and the body
wishes to do P'Access, of an access type declared outside the generic
unit.  This is illegal, but one can move the declaration of the
subprogram to the private part of the generic, and declare a
constant, also in the private part:

    P_Access: constant Global_Access_To_Subprogram_Type := P'Access;

Similarly, type extensions can be declared in the private part of the
generic when they are illegal in the body.

For the Access attribute for objects, a different workaround is
possible -- use Unchecked_Access instead.  Unfortunately, this throws
away all the benefit of the accessibility checks, and can lead to
erroneous execution if one is not careful.

Another case is for type conversion of an access type declared in the
generic unit (spec or body) to a type global to the generic unit.
This is currently illegal.  A possible workaround is to add a
conversion function to the generic body:

    function Convert(Ptr: access ...) return Global_Access_Type is
    begin
        return Global_Access_Type(Ptr);
    end Convert;

Then, if X is of the inner access type, Convert(X) will do a run-time
check, which will fail if and only if the current instance is more
nested than the generic unit.

All of the above workarounds are annoying, because they cause trouble
when converting a package into a generic package -- one has to apply
the above workarounds after having written and tested the non-generic
package.

One possible solution to the above problems is to define some extra
syntax, or a pragma that means "this generic unit will be
instantiated only at the same nesting level".  However, extra syntax
for a small issue seems like too big a change at this point.  And a
pragma with such a heavy semantic effect seems ugly.

Perhaps a better solution would be to say that all accessibility
rules are checked at run time in instance bodies.  (Doing things at
run time is one way of getting around generic contract model
problems in general, and it would work here.)  An implementation that
does macro expansion for generic instantiations could always detect
these "run-time" errors at macro-expansion time.  An implementation
that does code sharing would have to generate code to do the run-time
checks.

One problem with either solution is that there is a substantial
implementation burden for implementations that do universal generic
code sharing.  For such implementions, when a subprogram declared
inside the generic unit is called, it needs to be implicitly passed
an extra parameter that represents the current instance.  This extra
parameter is used by the subprogram to address variables declared in
the generic body.

Since such subprograms have a different calling convention, if one
allows access values pointing at them to escape outside the generic,
then one has a problem.

We recommend using the run-time accessibility checking solution.
However, because of the implementation problem, we recommend using this
solution only for access-to-object types, and not solving the problem
for access-to-subprogram types.  The implementation problem mentioned
above does not exist for access-to-object types.  This solution is not
entirely consistent, but note that it is already the case that
access-to-subprogram types are different: there are no anonymous
access-to-subprogram types, and there is no Unchecked_Access attribute
for these types.

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

SUMMARY:

Downward closures can be sensibly supported, and are quite desirable,
but cause implementation difficulties for display-based
implementations.  Therefore, we recommend not solving this problem.

Removing the accessibility restrictions on generic bodies can also be
sensibly supported, and is also desirable, but (for access-to-subprogram
types) presents severe implementation difficulties for implementations
that do universal sharing of generic bodies.  We recommend solving the
problem for access-to-object types by using run-time checks.  We
recommend not solving the problem for access-to-subprogram types.

-- 
Change robert to bob to get my real email address.  Sorry.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00           ` Subverting 'Access for Sub-programs adam
@ 1999-08-06  0:00             ` Robert A Duff
  1999-08-06  0:00               ` adam
  0 siblings, 1 reply; 68+ messages in thread
From: Robert A Duff @ 1999-08-06  0:00 UTC (permalink / raw)


adam@irvine.com writes:

> Actually, posts on this thread that I read after writing the above,
> along with some lookup in DejaNews, have mostly answered my question.
> However, the discussions I found in DejaNews mentioned proposals to put
> restrictions on assignment of these types, but not runtime checks.  Was
> anything like this seriously considered?

There was one proposal that involved run-time checks (see my other
posting), but I'm not sure it matches the kinds of run-time checks
you're thinking of.  I don't think anybody ever proposed a feature where
you could form a pointer to a (possibly-nested) subprogram, and then
check the validity of this pointer at the call site.  Such a feature
would be difficult to implement efficiently.  In fact, if you're going
*that* far, I suspect you might as well go all the way to full closures,
as in various Lisp-style languages.

>...Would it be simpler to
> implement than the other solutions (for implementations that use
> displays)?

Well, the totally-unchecked version of downward closures causes
difficulty for display-based implementations, so it's hard to see how
any version with checks (compile time or run time) could make things
easier.

- Bob
-- 
Change robert to bob to get my real email address.  Sorry.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-06  0:00             ` Robert Dewar
@ 1999-08-06  0:00               ` Robert A Duff
  1999-08-08  0:00                 ` Brian Rogoff
  1999-08-09  0:00                 ` Tucker Taft
  0 siblings, 2 replies; 68+ messages in thread
From: Robert A Duff @ 1999-08-06  0:00 UTC (permalink / raw)


Robert Dewar <robert_dewar@my-deja.com> writes:

> Well this has been dealt with in length in previous threads,
> so it is not appropriate to repeat it, but briefly, an extension
> of a tagged type with new overriding primitives clearly
> generates the possibility of dispatching to these new
> primitives. If you allow extension in a smaller scope, you
> can obviously generate dangling pointers for these methods,
> using class variables whose value is the inner derived type.
> It would thus be unsafe to allow this extension.

Tucker and I discussed a design for allowing nested type extensions for
*limited* types, which would have prevented the dangling pointer issues.
I don't remember if we ever formally proposed this idea in public, or if
we killed it ourselves before it was seen by any reviewers.  I think it
involved a lot of implementation burden, and I have vague recollections
of worrying about the mob of generic-body-sharing compiler writers we
would have had to flee from...

Another idea, which was never seriously considered, would be to allow
nested type extensions, and then check at run time upon leaving a scope
that there are no objects with that 'Tag still in existence.  That
design could be made to work, but there are plenty of problems with it.

- Bob
-- 
Change robert to bob to get my real email address.  Sorry.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-06  0:00             ` Robert A Duff
@ 1999-08-06  0:00               ` adam
  1999-08-09  0:00                 ` Mark Biggar
  1999-08-09  0:00                 ` Robert A Duff
  0 siblings, 2 replies; 68+ messages in thread
From: adam @ 1999-08-06  0:00 UTC (permalink / raw)


In article <wccu2qdnidg.fsf@world.std.com>,
  Robert A Duff <bobduff@world.std.com> wrote:

> There was one proposal that involved run-time checks (see my other
> posting),

Note: I haven't looked at this yet.

> but I'm not sure it matches the kinds of run-time checks
> you're thinking of.  I don't think anybody ever proposed a feature
> where
> you could form a pointer to a (possibly-nested) subprogram, and then
> check the validity of this pointer at the call site.  Such a feature
> would be difficult to implement efficiently.

After I wrote the above post, I actually did think of a simple way
that this type of runtime check could be implemented efficiently.
Suppose you have a subprogram P that contains nested subprograms Q1,
Q2, etc.  If Q1'ACCESS is used, the compiler allocates a global counter
for P (Q1's parent); the access value for Q1'ACCESS would contain the
address of P's global counter, and the current value of the counter.
When P exits, it increments the global counter just before returning.
Now, any access-subprogram type that has this property will have a
counter address (possibly null) and a current counter value; so when
dereferencing, the program would look up the pointed-to counter and see
if its value matches the value stored in the access-subprogram type.  If
not, the dereference is illegal.  (A null counter address would indicate
a global subprogram, or perhaps any subprogram that is statically not
deeper than the type, so that the check would be unnecessary.)

P's counter would also have to be incremented when its execution is
abandoned due to an exception; this may add a little complication in
some implementations, but not too much.  Tasking probably complicates
things.

                                -- Adam



Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-05  0:00           ` Ray Blaak
@ 1999-08-06  0:00             ` Jean-Pierre Rosen
  1999-08-06  0:00               ` Hyman Rosen
  1999-08-06  0:00             ` Robert Dewar
  1 sibling, 1 reply; 68+ messages in thread
From: Jean-Pierre Rosen @ 1999-08-06  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1733 bytes --]


Ray Blaak <blaak@infomatch.com> a �crit dans le message :
m3iu6tjw2d.fsf@vault83.infomatch.bc.ca...
> Robert Dewar <robert_dewar@my-deja.com> writes:
> > But it is pretty fundamental and obvious that a tagged type
> > cannot be extended in a temporary inner scope, no?
>
> It is not fundamental and obvious to me. Perhaps you could explain.
>
> I am aware of implementation concerns with allowing such a thing, but the
> restriction seems is an exception to the generality of declaring Ada
> constructs that is usually allowed.
>
> One can declare types, exceptions, variables, and routines anywhere,
except for
> tagged types. This restriction prevents a completely localized programming
> style when doing OO stuff.
>
Remember that tagged types basically include an array of pointers to
subprograms, so the restrictions on tagged types are the same as those on
pointers to subprograms.

I find it a bit unfair to blame Ada for these restrictions. C++, Eiffel,
Java have no embedded subprograms. Turbo-Pascal with objects (I gave up with
Turbo-Pascal before it became Delphi, but I guess it is the same for Delphi)
allows classes only at the top level. In all these case, there is no issue
since everything MUST be global. Ada's restriction is that derivations must
occur at the same level as the parent type, while other languages force
derivations only at level 1. So Ada is actually more liberal than other OO
languages I know of. You may regret that Ada is not even more liberal, but
please consider that the situation is better than other languages.

--
---------------------------------------------------------
           J-P. Rosen (Rosen.Adalog@wanadoo.fr)
Visit Adalog's web site at http://perso.wanadoo.fr/adalog







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

* Re: Subverting 'Access for Sub-programs
  1999-08-06  0:00             ` Jean-Pierre Rosen
@ 1999-08-06  0:00               ` Hyman Rosen
  1999-08-07  0:00                 ` Florian Weimer
  0 siblings, 1 reply; 68+ messages in thread
From: Hyman Rosen @ 1999-08-06  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=us-ascii, Size: 454 bytes --]

"Jean-Pierre Rosen" <rosen.adalog@wanadoo.fr> writes:
> Ray Blaak <blaak@infomatch.com> a ��crit dans le message :
> m3iu6tjw2d.fsf@vault83.infomatch.bc.ca...
> I find it a bit unfair to blame Ada for these restrictions. C++, Eiffel,
> Java have no embedded subprograms.

C++ does allow you to declare a derived class inside a function,
including new member functions. This only affects visibility, but
sometimes that's what you want.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-06  0:00         ` Brian Rogoff
@ 1999-08-07  0:00           ` Gautier
  0 siblings, 0 replies; 68+ messages in thread
From: Gautier @ 1999-08-07  0:00 UTC (permalink / raw)
  To: Brian Rogoff

Brian Rogoff wrote:

> > RR software has full generics sharing.
> 
> Anyone do sometimes share / sometimes expand? I'm curious.

DEC Ada does (/OPTIMIZE=...)

     The SHARE secondary option can have the following values:

     NONE          Disables generic sharing. This option overrides
                   the effect of any occurrences of the pragma SHARE_
                   GENERIC in the source code, without your having to
                   edit the source file. In addition, instances do not
                   share code from previous instantiations.
     NORMAL        Provides normal generic sharing. Normally, the
                   compiler will not attempt to generate shareable
                   code for an instance (code that can be shared
                   by subsequent instantiations) unless an explicit
                   pragma SHARE_GENERIC applies to that instance.
                   However, an instance will attempt to share code
                   that resulted from a previous instantiation to
                   which the pragma SHARE_GENERIC applied.
     MAXIMAL       Provides maximal generic sharing. The compiler
                   assumes that a pragma SHARE_GENERIC applies to
                   every instance in the unit being compiled unless
                   an explicit pragma INLINE_GENERIC applies. Thus, an
                   instance will attempt to share code that resulted
                   from a previous instantiation or to generate code
                   that can be shared by subsequent instantiations.

-- 
Gautier

--------
http://members.xoom.com/gdemont/




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

* Re: Subverting 'Access for Sub-programs
  1999-08-06  0:00               ` Hyman Rosen
@ 1999-08-07  0:00                 ` Florian Weimer
  0 siblings, 0 replies; 68+ messages in thread
From: Florian Weimer @ 1999-08-07  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> writes:

> C++ does allow you to declare a derived class inside a function,
> including new member functions. This only affects visibility, but
> sometimes that's what you want.

There are some limitations, too.  Local classes, as they are called by
the standard, aren't allowed to define static data members.  In additon,
it is impossible to access auto variables in the enclosing function
directly (you have to pass pointers and/or references, which can be
dangerous, or copy the objects, which can be expensive).




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

* Re: Subverting 'Access for Sub-programs
  1999-08-06  0:00               ` Robert A Duff
@ 1999-08-08  0:00                 ` Brian Rogoff
  1999-08-09  0:00                   ` Robert A Duff
  1999-08-09  0:00                 ` Tucker Taft
  1 sibling, 1 reply; 68+ messages in thread
From: Brian Rogoff @ 1999-08-08  0:00 UTC (permalink / raw)


On Fri, 6 Aug 1999, Robert A Duff wrote:
> Robert Dewar <robert_dewar@my-deja.com> writes:
> 
> > Well this has been dealt with in length in previous threads,
> > so it is not appropriate to repeat it, but briefly, an extension
> > of a tagged type with new overriding primitives clearly
> > generates the possibility of dispatching to these new
> > primitives. If you allow extension in a smaller scope, you
> > can obviously generate dangling pointers for these methods,
> > using class variables whose value is the inner derived type.
> > It would thus be unsafe to allow this extension.
> 
> Tucker and I discussed a design for allowing nested type extensions for
> *limited* types, which would have prevented the dangling pointer issues.
> I don't remember if we ever formally proposed this idea in public, or if
> we killed it ourselves before it was seen by any reviewers.  I think it
> involved a lot of implementation burden, and I have vague recollections
> of worrying about the mob of generic-body-sharing compiler writers we
> would have had to flee from...

Where have people found the inability to do nested type extensions
annoying, besides cases where you're using tagged types to simulate 
downward funargs? I have wanted them when trying to work around the lack
of downward funargs, but otherwise their omission hasn't been a big burden 
to me. Are there some compelling examples that I just haven't run across? 

I suspect that a downward funarg solution would handle most cases where a 
nested type extension was desired, provided the original tagged type 
provided for this possibility by having some primitive subprograms with
access to subprogram args.

> Another idea, which was never seriously considered, would be to allow
> nested type extensions, and then check at run time upon leaving a scope
> that there are no objects with that 'Tag still in existence.  That
> design could be made to work, but there are plenty of problems with it.

So, only allow this for descendants of (possibly limited) Controlled
types, or some similar special type?

-- Brian






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

* Re: Subverting 'Access for Sub-programs
  1999-08-08  0:00                 ` Brian Rogoff
@ 1999-08-09  0:00                   ` Robert A Duff
  1999-08-10  0:00                     ` Brian Rogoff
  0 siblings, 1 reply; 68+ messages in thread
From: Robert A Duff @ 1999-08-09  0:00 UTC (permalink / raw)


Brian Rogoff <bpr@shell5.ba.best.com> writes:

> So, only allow this for descendants of (possibly limited) Controlled
> types, or some similar special type?

I don't see how that helps.  If you have a global "type Ptr is access
all Something'Class", and you have a (illegal in Ada) type extension
local to some procedure, then you could end up with a global pointer
referencing an object of the local type (ie with the local 'Tag).
Finalizing it doesn't make any difference -- you still have a pointer to
a thing that contains dangling pointers (to the primitive ops).

- Bob

-- 
Change robert to bob to get my real email address.  Sorry.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-06  0:00               ` adam
  1999-08-09  0:00                 ` Mark Biggar
@ 1999-08-09  0:00                 ` Robert A Duff
  1 sibling, 0 replies; 68+ messages in thread
From: Robert A Duff @ 1999-08-09  0:00 UTC (permalink / raw)


adam@irvine.com writes:

> After I wrote the above post, I actually did think of a simple way
> that this type of runtime check could be implemented efficiently.
> Suppose you have a subprogram P that contains nested subprograms Q1,
> Q2, etc.  If Q1'ACCESS is used, the compiler allocates a global counter
> for P (Q1's parent); the access value for Q1'ACCESS would contain the
> address of P's global counter, and the current value of the counter.
> When P exits, it increments the global counter just before returning.
> Now, any access-subprogram type that has this property will have a
> counter address (possibly null) and a current counter value; so when
> dereferencing, the program would look up the pointed-to counter and see
> if its value matches the value stored in the access-subprogram type.  If
> not, the dereference is illegal.  (A null counter address would indicate
> a global subprogram, or perhaps any subprogram that is statically not
> deeper than the type, so that the check would be unnecessary.)

This is sort of like the "generation count" scheme, which we use in the
AdaMagic run-time system to detect dangling task id's.  You can use this
to detect dangling pointers in general, but it's rather expensive for
smallish things -- doubles the size of all the pointers, and increases
the number of memory references.  I'd rather have full garbage
collection.

> P's counter would also have to be incremented when its execution is
> abandoned due to an exception; this may add a little complication in
> some implementations, but not too much.

Or an abort statement or ATC.

>...Tasking probably complicates
> things.

Yeah.  I guess you would need a per-task count (and per-task data is
expensive on some systems).  Your scheme could work, but I still stand
by my statement, "Such a feature would be difficult to implement
efficiently."

- Bob
-- 
Change robert to bob to get my real email address.  Sorry.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-06  0:00               ` adam
@ 1999-08-09  0:00                 ` Mark Biggar
  1999-08-09  0:00                 ` Robert A Duff
  1 sibling, 0 replies; 68+ messages in thread
From: Mark Biggar @ 1999-08-09  0:00 UTC (permalink / raw)




> After I wrote the above post, I actually did think of a simple way
> that this type of runtime check could be implemented efficiently.
> Suppose you have a subprogram P that contains nested subprograms Q1,
> Q2, etc.  If Q1'ACCESS is used, the compiler allocates a global counter
> for P (Q1's parent); the access value for Q1'ACCESS would contain the
> address of P's global counter, and the current value of the counter.
> When P exits, it increments the global counter just before returning.
> Now, any access-subprogram type that has this property will have a
> counter address (possibly null) and a current counter value; so when
> dereferencing, the program would look up the pointed-to counter and see
> if its value matches the value stored in the access-subprogram type.  If
> not, the dereference is illegal.  (A null counter address would indicate
> a global subprogram, or perhaps any subprogram that is statically not
> deeper than the type, so that the check would be unnecessary.)
>
> P's counter would also have to be incremented when its execution is
> abandoned due to an exception; this may add a little complication in
> some implementations, but not too much.  Tasking probably complicates
> things.

This scheme fails if P is recursive.  Exiting recursive invocations of P
would invalidate
the function pointer even though the frame it depends on was still valid.

--
Mark Biggar
mark.a.biggar@lmco.com






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

* Re: Subverting 'Access for Sub-programs
  1999-08-06  0:00             ` Robert Dewar
@ 1999-08-09  0:00               ` Tucker Taft
  1999-08-10  0:00                 ` Robert Dewar
  0 siblings, 1 reply; 68+ messages in thread
From: Tucker Taft @ 1999-08-09  0:00 UTC (permalink / raw)


Robert Dewar wrote:
> ...
> 3. For subprograms, Unrestricted_Access provides a general
> mechanism corresponding really to what would more naturally
> be called Unchecked_Access, and to me the natural extension
> in the language would be to use Unchecked_Access for the
> purpose. I don't see any big semantic problem here. Pointers
> generated by the use of UA are the same as any other pointers
> generated by use of UA, namely you had better not use them
> when the corresponding referenced gizmo (be it an object as
> now allowed in the language, or a subprogram, as now forbidden)
> goes out of scope. The implementation impact is no worse than
> will be required for general downward funargs, so if you buy
> the latter, why not allow Unchecked_Access on subprograms as
> the natural extension.

The reason we didn't allow Unchecked_Access for subprograms was
that the definition of being "out of scope" depends on whether
you are using static links or (per-task) displays.  If you are using
static links, then a subprogram is out of scope if you have exited the
frame in which the subprogram was declared.  For displays, the subprogram
is out of scope anyplace where you are not *lexically* enclosed by
the frame in which the subprogram is declared, because the display 
(which is presumably *not* passed along with a 'Unchecked_Access
access-to-subprogram value) changes when you change the *lexical*
enclosing environment.

This reason hasn't changed, so I would still resist allowing
'Unchecked_Access to apply to subprograms unless we can agree
on a definition of where and when the values created by unchecked-access
can be used, independent of whether static links or displays are
used underneath.

One approach that helps is to require that a subprogram that is
to be subject to 'Unrestricted_Access, as well as the access-to-subp
type that is going to allow its use, be marked with some kind of
"pragma Unrestricted_Access" (analogous to marking an object with "aliased"
and marking general access types with "all").  This would prevent
distributed overhead for other subprograms/access-to-subp types.
> 
> I think that even if you implement the "safe" downward funargs
> features, you will still feel a need for UA on subprograms. The
> situations in which you need this are exactly similar to those
> which cause you to use UA for objects, e.g. you want to park
> pointers in some global structures, for later use, and you
> happen to know that your logic is such that they will not be
> used after the referenced gizmo has gone out of scope.
> 
> For example, I have a general library level procedure that does
> callbacks, and expects to be passed a record containing the
> stuff necessary for the callback processing, including an
> access-to-subprogram value. Currently I can't use a nested
> subprogram for that purpose which is annoying, and the "safe"
> proposal still won't allow it.

True, but you will need to come up with the display-based implementation
for this that doesn't incur distributed overhead for other
access-to-subp uses (which currently don't require any display
"fiddling" on call and can use single pointers for access-to-subp values).
I think a "pragma Unrestricted_Access" may be needed...

> Robert Dewar

-- 
-Tucker Taft   stt@averstar.com   http://www.averstar.com/~stt/
Technical Director, Distributed IT Solutions  (www.averstar.com/tools)
AverStar (formerly Intermetrics, Inc.)   Burlington, MA  USA




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

* Re: Subverting 'Access for Sub-programs
  1999-08-06  0:00               ` Robert A Duff
  1999-08-08  0:00                 ` Brian Rogoff
@ 1999-08-09  0:00                 ` Tucker Taft
  1 sibling, 0 replies; 68+ messages in thread
From: Tucker Taft @ 1999-08-09  0:00 UTC (permalink / raw)


Robert A Duff wrote:
> ...
> Tucker and I discussed a design for allowing nested type extensions for
> *limited* types, which would have prevented the dangling pointer issues.
> I don't remember if we ever formally proposed this idea in public, or if
> we killed it ourselves before it was seen by any reviewers.  I think it
> involved a lot of implementation burden, and I have vague recollections
> of worrying about the mob of generic-body-sharing compiler writers we
> would have had to flee from...

It isn't that bad.  It was all described in the Language Design Note
that you posted to this News thread just a little while ago.
Any additional information needed in the way of static links,
displays, etc., gets added to the representation of the type
as part of the nested (limited) extension.
> 

> 
> - Bob
-- 
-Tucker Taft   stt@averstar.com   http://www.averstar.com/~stt/
Technical Director, Distributed IT Solutions  (www.averstar.com/tools)
AverStar (formerly Intermetrics, Inc.)   Burlington, MA  USA




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

* Re: Subverting 'Access for Sub-programs
  1999-08-09  0:00               ` Tucker Taft
@ 1999-08-10  0:00                 ` Robert Dewar
  1999-08-11  0:00                   ` Dmitry A. Kazakov
                                     ` (2 more replies)
  0 siblings, 3 replies; 68+ messages in thread
From: Robert Dewar @ 1999-08-10  0:00 UTC (permalink / raw)


In article <37AEF7BF.7BBC8E06@averstar.com>,
  Tucker Taft <stt@averstar.com> wrote:
> The reason we didn't allow Unchecked_Access for subprograms
was
> that the definition of being "out of scope" depends on whether
> you are using static links or (per-task) displays.  If you are
using
> static links, then a subprogram is out of scope if you have
exited the
> frame in which the subprogram was declared.  For displays, the
subprogram
> is out of scope anyplace where you are not *lexically*
enclosed by
> the frame in which the subprogram is declared, because the
display
> (which is presumably *not* passed along with a
'Unchecked_Access
> access-to-subprogram value) changes when you change the
*lexical*
> enclosing environment.


You are missing the context here Tuck. Yes, we all understand
that the annoying restriction in the language comes from making
life easier for the display folks. I have explained this myself
many times.

The discussion we were having is what should be done to the
language design if you abandon this annoying non-technical
consideration.

It is in that context that I suggest that Unchecked_Access
would be appropriately allowed for subprograms with the
obvious semantics (if you absolutely *must* think in
implementation terms, the static link semantics that you
mention above :-)

Yes, this would be annoying for the display folks, because, just
as is necessary in Pascal if you use displays, you need to save
the display as part of a subprogram access value. THis is not
possible, but it is probably not the right approach.

If you still agree that the non-technical arguments for making
life easier for the display folks are operable, then of course
you won't agree with this entire line of thought.

The predicate for this discussion is that we are assuming that
it is NOT reasonable to continue to walk around doing the design
with this ball-and-chain attached to our feet, and we are
wondering what the language should look like if we take a file
and cut it off :-)

Yes, we probably want the limited-access types that are
completely safe, but I would also put in the Unchecked_Access
possibility, since it will cover additional useful cases. I
would not go as far as the Unrestricted_Access semantics of
GNAT for objects in any case as part of a semi-standard proposal
since aspects of this (accesses-to-slices for example) are
highly implementation dependent.

What I was saying is that the diction in GNAT:

   subprog'Unrestricted_Access

would more reasonably be called

   subprog'Unchecked_Access

if we did not have an arbitrary rule in the current Ada
standard forbidding us from allowing this. Actually we might
well allow this with the -gnatX (extensions allowed) switch :-)

Robert Dewar
Ada Core Technologies

P.S. just in case people get alarmed by the mention of -gnatX,
the only extension currently there is the semi-respectable
"with type" capability.


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-09  0:00                   ` Robert A Duff
@ 1999-08-10  0:00                     ` Brian Rogoff
  0 siblings, 0 replies; 68+ messages in thread
From: Brian Rogoff @ 1999-08-10  0:00 UTC (permalink / raw)


On Mon, 9 Aug 1999, Robert A Duff wrote:

> Brian Rogoff <bpr@shell5.ba.best.com> writes:
> 
> > So, only allow this for descendants of (possibly limited) Controlled
> > types, or some similar special type?
> 
> I don't see how that helps.  If you have a global "type Ptr is access
> all Something'Class", and you have a (illegal in Ada) type extension
> local to some procedure, then you could end up with a global pointer
> referencing an object of the local type (ie with the local 'Tag).
> Finalizing it doesn't make any difference -- you still have a pointer to
> a thing that contains dangling pointers (to the primitive ops).

Yup, I know you can't use finalization to get this; I thought you were 
proposing a similar "distinguished tagged type" mechanism analogous to 
controlled types for nested extensions, but on rereading what you wrote 
I think that I must have hallucinated it :-).

In any case, I still think nested type extensions are a lot less useful
than a direct downward funarg capability.

-- Brian






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

* Re: Subverting 'Access for Sub-programs
  1999-08-10  0:00                 ` Robert Dewar
  1999-08-11  0:00                   ` Dmitry A. Kazakov
@ 1999-08-11  0:00                   ` Robert A Duff
  1999-08-11  0:00                     ` Robert Dewar
  1999-08-11  0:00                   ` Tucker Taft
  2 siblings, 1 reply; 68+ messages in thread
From: Robert A Duff @ 1999-08-11  0:00 UTC (permalink / raw)


Robert Dewar <robert_dewar@my-deja.com> writes:

> Yes, this would be annoying for the display folks, because, just
> as is necessary in Pascal if you use displays, you need to save
> the display as part of a subprogram access value. THis is not
                                                            ^^^
> possible, but it is probably not the right approach.
  ^^^^^^^^
I think that's a typo -- you meant "not IMpossible" = "possible"?

I know of one Pascal compiler that used displays and implemented
downward closures, which proves that it's not only possible, but
feasible.  But I agree that it's not the right aproach.

> Yes, we probably want the limited-access types that are
> completely safe, but I would also put in the Unchecked_Access
> possibility, since it will cover additional useful cases.

You've convinced *me* that the Unch_Acc on subprogs has its uses.
Tucker, on the other hand, has a different point of view toward
nesting in general ("for the birds").

>... I
> would not go as far as the Unrestricted_Access semantics of
> GNAT for objects in any case as part of a semi-standard proposal
> since aspects of this (accesses-to-slices for example) are
> highly implementation dependent.

One thing that bothers me about the object'un_acc thing, is that if the
object is not addressable (component of something packed), then it just
gives a "wrong" answer -- wrong in the sense that the result doesn't
point at the object.  At least that's my understanding, since you've
defined 'unr_acc in terms of 'address, which also has this
unfortunate behavior.

- Bob
-- 
Change robert to bob to get my real email address.  Sorry.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-11  0:00                   ` Robert A Duff
@ 1999-08-11  0:00                     ` Robert Dewar
  0 siblings, 0 replies; 68+ messages in thread
From: Robert Dewar @ 1999-08-11  0:00 UTC (permalink / raw)


In article <wccoggeii08.fsf@world.std.com>,
  Robert A Duff <bobduff@world.std.com> wrote:
> Robert Dewar <robert_dewar@my-deja.com> writes:
>
> > Yes, this would be annoying for the display folks, because,
just
> > as is necessary in Pascal if you use displays, you need to
save
> > the display as part of a subprogram access value. THis is
not
>
^^^
> > possible, but it is probably not the right approach.
>   ^^^^^^^^
> I think that's a typo -- you meant "not IMpossible" =
"possible"?

Indeed, thanks for pointing this out, I did indeed mean
not impossible. Consider this to be an AI reintepreting
my original message to say impossible instead of possible :-)




Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-11  0:00                   ` Dmitry A. Kazakov
  1999-08-11  0:00                     ` Richard D Riehle
@ 1999-08-11  0:00                     ` Robert Dewar
  1999-08-12  0:00                       ` Dmitry A. Kazakov
  1 sibling, 1 reply; 68+ messages in thread
From: Robert Dewar @ 1999-08-11  0:00 UTC (permalink / raw)


In article <37B18CF0.F50A802B@gandalf.atm.fh-luebeck.de>,
  "Dmitry A. Kazakov" <dmitry@gandalf.atm.fh-luebeck.de> wrote:
> I believe that the actual problem is in using pointers. In
90%, I would
> say, there is
> no need to pass a subroutine by pointer. It should be passed
by
> reference: What we
> need is something like (syntax is imaginary):


But passing subprograms as parameters is only one of many
possible uses of subprogram pointers. Indeed it is one of
the weakest uses, in that this particular use often can
be replaced by generics. The motivation for providing
pointers to subprograms during the Ada 95 design was
driven by other uses entirely, most notably by the need
for implementing call backs (and of course if you think
about it the use of procedure pointers implicit in
dynamic dispatching is also another kind of use completely
unrelated to the call by reference notion).

That being said, there is certainly nothing wrong with
providing a general capability here (as is done in Algol-68).


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-10  0:00                 ` Robert Dewar
  1999-08-11  0:00                   ` Dmitry A. Kazakov
  1999-08-11  0:00                   ` Robert A Duff
@ 1999-08-11  0:00                   ` Tucker Taft
  1999-08-13  0:00                     ` Robert Dewar
  1999-08-13  0:00                     ` Robert Dewar
  2 siblings, 2 replies; 68+ messages in thread
From: Tucker Taft @ 1999-08-11  0:00 UTC (permalink / raw)


Robert Dewar wrote:
> 
> In article <37AEF7BF.7BBC8E06@averstar.com>,
>   Tucker Taft <stt@averstar.com> wrote:
> > The reason we didn't allow Unchecked_Access for subprograms
> was
> > that the definition of being "out of scope" depends on whether
> > you are using static links or (per-task) displays.  If you are
> using
> > static links, then a subprogram is out of scope if you have
> exited the
> > frame in which the subprogram was declared.  For displays, the
> subprogram
> > is out of scope anyplace where you are not *lexically*
> enclosed by
> > the frame in which the subprogram is declared, because the
> display
> > (which is presumably *not* passed along with a
> 'Unchecked_Access
> > access-to-subprogram value) changes when you change the
> *lexical*
> > enclosing environment.
> 
> You are missing the context here Tuck. Yes, we all understand
> that the annoying restriction in the language comes from making
> life easier for the display folks. I have explained this myself
> many times.
> 
> The discussion we were having is what should be done to the
> language design if you abandon this annoying non-technical
> consideration.
> 
> It is in that context that I suggest that Unchecked_Access
> would be appropriately allowed for subprograms with the
> obvious semantics (if you absolutely *must* think in
> implementation terms, the static link semantics that you
> mention above :-)

I understood the point about not worrying about "display" 
difficulties for *checked* language mechanisms.  But for
something called "Unchecked_Access" I have always presumed
this is a mechanism that does the "obvious" thing, but just
doesn't perform any legality checks.  

What you are proposing is that the "official" semantics 
for Unchecked_Access impose a requirement that it "work" 
whenever you are *dynamically* within the 
scope of the called routine.  This implies a significant
amount of mechanism on the part of display-based implementations
to implement this, as opposed to simply eliminating the legality
checks at the point of 'Unchecked_Access.  

In other words, *all* access-to-subp values might have 
been produced by 'Unchecked_Access, so *all* calls 
through such values in a display-based implementation
must take that into account.  By adding 'Unchecked_Access, you would
be imposing a distributed overhead on all uses of access-to-subp values,
even if there is no 'Unchecked_Access in the whole program, in the
display-based implementation.  *That* is why I wouldn't want to call
this feature simply "Unchecked_Access."

> ...
> The predicate for this discussion is that we are assuming that
> it is NOT reasonable to continue to walk around doing the design
> with this ball-and-chain attached to our feet, and we are
> wondering what the language should look like if we take a file
> and cut it off :-)

I can see forcing implementors using displays to support a
more expensive mechanism under "new" circumstances, but I can't
see dramatically slowing down all uses of existing access-to-subp
values to support some additional feature.  That kind of distributed
overhead of a feature is quite unpleasant, especially as part of
a language revision.  We made major efforts during the Ada 9X
process to minimize new features that imposed distributed overhead
on old features.  (We succeeded in most cases, though clearly exception
handling is now more complicated given namable exception occurrences
and finalization.)
> 
> Yes, we probably want the limited-access types that are
> completely safe, but I would also put in the Unchecked_Access
> possibility, since it will cover additional useful cases. 

If we want an access-to-subp value that works any time you are still
within the "dynamic" scope of a subprogram, I believe we should
make it a different kind of access type.  Perhaps 
   type T is access all procedure ...
                    ^^^
or some kind of pragma Unrestricted, or something.  Even with
the static link approach, supporting Unchecked_Access on access-to-subp
values requires doubling the size of all "top-level" access-to-subp
values, or using some sort of "trampoline" trick.  Creating a
trampoline that has the right lifetime is a fair amount of work
as well, since the place of the 'Unchecked_Access is a bit late.
I realize that GNAT has solved this, but I believe it takes
significant advantage of work already performed as part of the GCC
nested procedure support.  And all this makes the 'Unchecked_Access
a significantly more "heavyweight" feature than is implied by
the name.  It is far from being simply the moral equivalent of
an unchecked-conversion.

> Robert Dewar
> Ada Core Technologies

-- 
-Tucker Taft   stt@averstar.com   http://www.averstar.com/~stt/
Technical Director, Distributed IT Solutions  (www.averstar.com/tools)
AverStar (formerly Intermetrics, Inc.)   Burlington, MA  USA




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

* Re: Subverting 'Access for Sub-programs
  1999-08-11  0:00                   ` Dmitry A. Kazakov
@ 1999-08-11  0:00                     ` Richard D Riehle
  1999-08-11  0:00                     ` Robert Dewar
  1 sibling, 0 replies; 68+ messages in thread
From: Richard D Riehle @ 1999-08-11  0:00 UTC (permalink / raw)


In article <37B18CF0.F50A802B@gandalf.atm.fh-luebeck.de>,
	"Dmitry A. Kazakov" <dmitry@gandalf.atm.fh-luebeck.de> wrote:

.... stuff deleted ...

>I believe that the actual problem is in using pointers. 

.... more stuff deleted

Blame it all on Maurice Wilkes who came up with this whole notion
of indirection in the first place (if my ancient memory of this is
correct).  Dr. Wilkes once said, "There is no problem in computer
programming that cannot be solved by yet one more level of indirection."
Ever since then, we have been solving problems via indirection (pointers).

Who was it that replied to Dr. Wilkes with, "The is no problem in computer
programming that cannot be made more complicated by yet one more level
of indirection." ?????  Perhaps it is time to revert to the good old 
days of Fortran and COBOL where everything was direct.  

I hope the humor of this is not lost on some reader.  I do not need to
be up to my neck in flames -- errrrrr, pointers to flames.

Richard Riehle
richard@adaworks.com
http://www.adaworks.com





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

* Re: Subverting 'Access for Sub-programs
  1999-08-10  0:00                 ` Robert Dewar
@ 1999-08-11  0:00                   ` Dmitry A. Kazakov
  1999-08-11  0:00                     ` Richard D Riehle
  1999-08-11  0:00                     ` Robert Dewar
  1999-08-11  0:00                   ` Robert A Duff
  1999-08-11  0:00                   ` Tucker Taft
  2 siblings, 2 replies; 68+ messages in thread
From: Dmitry A. Kazakov @ 1999-08-11  0:00 UTC (permalink / raw)



Robert Dewar wrote:

> The discussion we were having is what should be done to the
> language design if you abandon this annoying non-technical
> consideration.
>
> It is in that context that I suggest that Unchecked_Access
> would be appropriately allowed for subprograms with the
> obvious semantics (if you absolutely *must* think in
> implementation terms, the static link semantics that you
> mention above :-)

I believe that the actual problem is in using pointers. In 90%, I would
say, there is
no need to pass a subroutine by pointer. It should be passed by
reference: What we
need is something like (syntax is imaginary):

    type function ARealFunction (X : float) return float;

    function Integral (F : ARealFunction; From : float; To : float)
return float is
    begin
       ...
    end;

The key difference is that the function object must exist only at the
call point which is
clear from argument profile. The callee is unable to get its address and
store it.

In remaining 10% the restrictions on 'Access are meaningful and require
no back doors.

Regards,
Dmitry





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

* Re: Subverting 'Access for Sub-programs
  1999-08-11  0:00                     ` Robert Dewar
@ 1999-08-12  0:00                       ` Dmitry A. Kazakov
  1999-08-14  0:00                         ` Robert Dewar
  0 siblings, 1 reply; 68+ messages in thread
From: Dmitry A. Kazakov @ 1999-08-12  0:00 UTC (permalink / raw)



Robert Dewar wrote:

> In article <37B18CF0.F50A802B@gandalf.atm.fh-luebeck.de>,
>   "Dmitry A. Kazakov" <dmitry@gandalf.atm.fh-luebeck.de> wrote:
> > I believe that the actual problem is in using pointers. In
> 90%, I would
> > say, there is
> > no need to pass a subroutine by pointer. It should be passed by
> > reference: What we
> > need is something like (syntax is imaginary):
>
> But passing subprograms as parameters is only one of many
> possible uses of subprogram pointers. Indeed it is one of
> the weakest uses, in that this particular use often can
> be replaced by generics. The motivation for providing
> pointers to subprograms during the Ada 95 design was
> driven by other uses entirely, most notably by the need
> for implementing call backs (and of course if you think
> about it the use of procedure pointers implicit in
> dynamic dispatching is also another kind of use completely
> unrelated to the call by reference notion).

I do not argue against subprogram pointers. But it is a bit strange
to provide them without variables which values they point to. (:-))

As for call backs there are different sorts of them.

1. When pointer to call back will be copied by the callee, then
yes, it must be passed by pointer. Further, in this case it is pretty
meaningful not to allow 'unchecked_access which result could be
catastrophic in some contexts.

2. Otherwise (when used locally) it should be passed by reference,
which would lift all unnecessary (in this case) limitations of 'access.
The same way you pass a variable.

Best regards,
Dmitry





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

* Re: Subverting 'Access for Sub-programs
  1999-08-11  0:00                   ` Tucker Taft
@ 1999-08-13  0:00                     ` Robert Dewar
  1999-08-13  0:00                       ` Brian Rogoff
  1999-08-13  0:00                     ` Robert Dewar
  1 sibling, 1 reply; 68+ messages in thread
From: Robert Dewar @ 1999-08-13  0:00 UTC (permalink / raw)


In article <37B1A8B5.219C9FE6@averstar.com>,
  Tucker Taft <stt@averstar.com> wrote:

> I understood the point about not worrying about "display"
> difficulties for *checked* language mechanisms.  But for
> something called "Unchecked_Access" I have always presumed
> this is a mechanism that does the "obvious" thing, but just
> doesn't perform any legality checks.

Well it is clear that Unchecked_Access has to have clean clear
semantics, as it does for variables. Who knows what this means
in an implementation. For example, it is easy to imagine that
Unchecked_Access might be very hard to implement and require
lots of extra apparatus in an underlying environment that went
out of its way to ensure safety (e.g. something like a JVM).

> What you are proposing is that the "official" semantics
> for Unchecked_Access impose a requirement that it "work"
> whenever you are *dynamically* within the
> scope of the called routine.  This implies a significant
> amount of mechanism on the part of display-based
> implementations to implement this, as opposed to simply
> eliminating the legality checks at the point of
> 'Unchecked_Access.

Yes indeed, but then I think if you allow general downward
funargs you will need this extra mechanism in any case, and
the proper implementation approach is probably to switch to
static links.

> In other words, *all* access-to-subp values might have
> been produced by 'Unchecked_Access, so *all* calls
> through such values in a display-based implementation
> must take that into account.  By adding 'Unchecked_Access, you
> would be imposing a distributed overhead on all uses of
> access-to-subp values, even if there is no 'Unchecked_Access
> in the whole program, in the display-based implementation.
> *That* is why I wouldn't want to call
> this feature simply "Unchecked_Access."

Once again, I am simply putting this proposal on the table I
don't necessarily favor it. If you look back at my previous
messages, I was simply laying out the solution space, not
choosing a point in it!) I definitely agree that if the language
was designed this way, i.e. in the way that gives a natural
flexible, powerful, and efficient behavior if you use static
links, then precisely it would be the case that implementations
would pretty much be forced to use static links.

The issue here is whether you want to continue to cripple the
language (if you think the restrictions on procedure pointers
to be crippling as many do) just to make it easier for old
implementations using what is now a bad choice.

One viewpoint that could be taken is that such limitations were
appropriate early on in Ada 95, to increase the ease of
transition, but now that transition is complete, it is not
unreasonable to consider improvements that would cause some
implementation difficulties in some compilers. After all almost
any extension proposal will be harder for some compilers than
others.
>
> I can see forcing implementors using displays to support a
> more expensive mechanism under "new" circumstances, but I
> can't see dramatically slowing down all uses of existing
> access-to-subp values to support some additional feature.
> That kind of distributed overhead of a feature is quite
> unpleasant, especially as part of a language revision.  We
> made major efforts during the Ada 9X process to minimize new
> features that imposed distributed overhead on old features.

We are not talking about that here, we are talking about the
limited case of old compilers not adapting to the more
appropriate implementation strategy.

The language should in abstract be designed so that there
exists (at least one) efficient implementation strategy.
That's quite a reasonable framework.

In the case of the display issue, we went further, and decided
to accomodate what, in the context of our language design
effort, was very definitely a bad choice of implementation
strategies.

The question is whether you want to insist on this much more
limited approach for ever.

There are many other places in the language where changes in
Ada 95 made things MUCH harder for some implementations (e.g.
making sharing of generics much harder).

> If we want an access-to-subp value that works any time you are
> still within the "dynamic" scope of a subprogram, I believe we
> should
> make it a different kind of access type.  Perhaps
>    type T is access all procedure ...
>                     ^^^
> or some kind of pragma Unrestricted, or something.  Even with
> the static link approach, supporting Unchecked_Access on
> access-to-subp
> values requires doubling the size of all "top-level"
> access-to-subp
> values, or using some sort of "trampoline" trick.  Creating a
> trampoline that has the right lifetime is a fair amount of
> work
> as well, since the place of the 'Unchecked_Access is a bit
> late.
> I realize that GNAT has solved this, but I believe it takes
> significant advantage of work already performed as part of the
> GCC
> nested procedure support.  And all this makes the
> 'Unchecked_Access
> a significantly more "heavyweight" feature than is implied by
> the name.  It is far from being simply the moral equivalent of
> an unchecked-conversion.

I must say I really dislike the idea of procedure pointers being
a different length at the top level and nested levels, sounds
like a really nasty non-uniformity, so I would definitely avoid
that.

Note that the unchecked in unchecked_access to me is about
lack of checks at run time, and indeed no checks are required
at run time.

As I noted earlier, I can easily imagine environments in which
unchecked_access imposes a distributed overhead on all uses
of access values!

Really what we need to do at this stage is to try to get some
idea of what the Ada user community wants. GNAT users are not
the best source of help here, since the problem is already
completely solved in GNAT (although of course not in a portable
manner!)

For users of other compilers, how much of a restriction is it
to have access-to-procedure have the limitations of the current
Ada 95 design, that is the question.

I certainly know, as I have previously noted, that we make
extensive use of Unrestricted_Access in the GNAT runtime (there
are well over 100 instances in gnatlib). This is certainly not
typical. First, a lot of it is low level system type code,
second, you tend to use features that are available if it is
the easiest way of doing things, and it does not always mean
that you couldn't manage OK without them :-)


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-11  0:00                   ` Tucker Taft
  1999-08-13  0:00                     ` Robert Dewar
@ 1999-08-13  0:00                     ` Robert Dewar
  1 sibling, 0 replies; 68+ messages in thread
From: Robert Dewar @ 1999-08-13  0:00 UTC (permalink / raw)


In article <37B1A8B5.219C9FE6@averstar.com>,
  Tucker Taft <stt@averstar.com> wrote:

> or using some sort of "trampoline" trick.  Creating a
> trampoline that has the right lifetime is a fair amount of
> wor as well, since the place of the 'Unchecked_Access is a bit
> late. I realize that GNAT has solved this, but I believe it
> takes significant advantage of work already performed as part
> of the GCC nested procedure support.

Actually I don't see any lifetime problems, as long as the
trampoline is placed in the stack frame of the enclosing
subprogram, as is done in GNAT.

However, there are real problems in trampolines -- first the
whole issue of cache coherency in Harvard style architectures,
and second the issue of write protection of the stack (Sun has
a configuration option to do this, but it is troublesome enough
that it is very rarely used).

GNAT has solved these problems yes, but there are efficiency
concerns on some architectures.

SO I would agree with Tuck that the possibility of using
trampolines should not be something that is factored in.
In other words if the ADa definition *requires* trampolines
then I think that is a bad choice.

The alternative is as Tuck notes, two words per procedure
access value, and an extra load on the call. How bad is that?
Hard to say, the trade off is this extra space and time,
compared to extra complexity in having a separate type.

Note that on some architectures, notably from Digital, where
all indirect calls go through a procedure descriptor in any
case, there is no additional overhead at all (if you like, it
is already incurred unconditionally!)

Robert Dewar
Ada Core Technologies


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-13  0:00                     ` Robert Dewar
@ 1999-08-13  0:00                       ` Brian Rogoff
  0 siblings, 0 replies; 68+ messages in thread
From: Brian Rogoff @ 1999-08-13  0:00 UTC (permalink / raw)


On Fri, 13 Aug 1999, Robert Dewar wrote:
> Really what we need to do at this stage is to try to get some
> idea of what the Ada user community wants. GNAT users are not
> the best source of help here, since the problem is already
> completely solved in GNAT (although of course not in a portable
> manner!)

I think GNAT users are as good a source of help as any other
implementation bound subset of Ada users. At least GNAT users 
can speak from experience as to how useful Unrestricted_Access 
is, what contexts they use it in, etc. I can tell you that I much 
prefer it to using generics to simulate downward funargs, though I almost
always use generics because that approach is portable between compilers.
From the question which started this thread, I presume many people agree. 
I still think generic subprograms are useful for type checking, like 
the "where clauses" of CLU and Theta, but as downward funargs they only 
provide a clumsy workaround, IMO of course :-).

> For users of other compilers, how much of a restriction is it
> to have access-to-procedure have the limitations of the current
> Ada 95 design, that is the question.
> 
> I certainly know, as I have previously noted, that we make
> extensive use of Unrestricted_Access in the GNAT runtime (there
> are well over 100 instances in gnatlib). This is certainly not
> typical. First, a lot of it is low level system type code,
> second, you tend to use features that are available if it is
> the easiest way of doing things, and it does not always mean
> that you couldn't manage OK without them :-)

Well, since much of the philosophy of Ada is about readability,
maintainability, reusable libraries, etc., the fact that the 
use of these GNAT extensions makes programming easier is telling!

I certainly wouldn't abandon Ada over this deficiency, but given the 
fact that Ada has nested functions and lexical scope, the absence of 
direct support for downward funargs is very irritating. 

-- Brian






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

* Re: Subverting 'Access for Sub-programs
  1999-08-12  0:00                       ` Dmitry A. Kazakov
@ 1999-08-14  0:00                         ` Robert Dewar
  1999-08-16  0:00                           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 68+ messages in thread
From: Robert Dewar @ 1999-08-14  0:00 UTC (permalink / raw)


In article <37B2D220.9CAAD611@gandalf.atm.fh-luebeck.de>,
  "Dmitry A. Kazakov" <dmitry@gandalf.atm.fh-luebeck.de> wrote:
> 2. Otherwise (when used locally) it should be passed by
reference,
> which would lift all unnecessary (in this case) limitations of
'access.
> The same way you pass a variable.


Passing something by reference is completely equivalent to
passing it by pointer at the calling sequence level, and if
you are calling a C program, it could not care whether you
pass an array as an IN parameter, or pass a pointer to an
array. The same is true of procedures. Passing a procedure
by reference to foreign code would be identical to passing
it by pointer. Yes, if you are only talking about ada-to-ada
there is some protection (although I really think that the
scheme proposed by the design team in mapping document 2
is a lot neater, and you should review that thoroughly before
making your own suggestions).

But in practice call back programming VERY often involves
interfacing to external code, in which case passing by
reference vs passing by pointer is identical.


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Subverting 'Access for Sub-programs
  1999-08-14  0:00                         ` Robert Dewar
@ 1999-08-16  0:00                           ` Dmitry A. Kazakov
  0 siblings, 0 replies; 68+ messages in thread
From: Dmitry A. Kazakov @ 1999-08-16  0:00 UTC (permalink / raw)


Robert Dewar wrote:

> Passing something by reference is completely equivalent to
> passing it by pointer at the calling sequence level, and if
> you are calling a C program, it could not care whether you
> pass an array as an IN parameter, or pass a pointer to an
> array. The same is true of procedures. Passing a procedure
> by reference to foreign code would be identical to passing
> it by pointer.

Indeed but from implementation point of view only. From the
language point of view there is a great difference. Consider this:

   type PointerToInt is access all Integer;
   ExternalRef : PointerToInt;

   procedure Foo (X : Integer) is
   begin
      ExternalRef := X'access; -- Illegal!
   end Foo;
   procedure Foo (X : PointerToInt) is
   begin
      ExternalRef := X;           -- Legal!
   end Foo;

Further, the first version accepts all integer varaibles in all
contexts.
The second one:

   declare
       Temp : aliased Integer;
   begin
       Foo (Temp'access);   -- Illegal (for very good reason)
   end;

This is, I believe, exactly what we need for subprograms too.

> Yes, if you are only talking about ada-to-ada
> there is some protection (although I really think that the
> scheme proposed by the design team in mapping document 2
> is a lot neater, and you should review that thoroughly before
> making your own suggestions).

It is no matter which language is interfaced.

The interface (subprogram profile) should clarify whether
parameter (another subprogram) can be <'access>ed within
the callee or not. When you pass an object as-is, by reference
or by value, no matter (it is possible to imagine situation when
a subprogram is passed by copy (:-)), then its nesting is of no
importance. When you pass it by pointer, then you should
know what you do and all the limitations of 'access protect
unaware programmers (even if they do not want to be
protected (:-))

> But in practice call back programming VERY often involves
> interfacing to external code, in which case passing by
> reference vs passing by pointer is identical.

It always depends on WHAT the callee does. When you
create a modal dialog under Windows, the dialog procedure
can be passed by reference, for there is no return to caller
until dialog ends. It would work exactly identical to passing
by pointer with one great difference - without 'access (and
its unnecessary, in this case, limitations).

Best regards,
Dmitry





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

end of thread, other threads:[~1999-08-16  0:00 UTC | newest]

Thread overview: 68+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-08-03  0:00 Subverting 'Access for Sub-programs Anton Gibbs
1999-08-03  0:00 ` tmoran
1999-08-03  0:00 ` Steve Doiel
1999-08-03  0:00 ` Ted Dennison
1999-08-03  0:00 ` David C. Hoos, Sr.
1999-08-05  0:00   ` Robert A Duff
1999-08-03  0:00 ` Michael F. Yoder
1999-08-03  0:00 ` Brian Rogoff
1999-08-04  0:00 ` Robert Dewar
1999-08-04  0:00   ` Robert A Duff
1999-08-04  0:00     ` Robert Dewar
1999-08-04  0:00 ` Anton Gibbs
1999-08-04  0:00   ` Robert A Duff
1999-08-04  0:00     ` Brian Rogoff
1999-08-05  0:00       ` tmoran
1999-08-05  0:00         ` Aidan Skinner
1999-08-05  0:00         ` Robert Dewar
1999-08-05  0:00           ` Ray Blaak
1999-08-06  0:00             ` Jean-Pierre Rosen
1999-08-06  0:00               ` Hyman Rosen
1999-08-07  0:00                 ` Florian Weimer
1999-08-06  0:00             ` Robert Dewar
1999-08-06  0:00               ` Robert A Duff
1999-08-08  0:00                 ` Brian Rogoff
1999-08-09  0:00                   ` Robert A Duff
1999-08-10  0:00                     ` Brian Rogoff
1999-08-09  0:00                 ` Tucker Taft
1999-08-05  0:00     ` Anton Gibbs
1999-08-04  0:00   ` Jean-Pierre Rosen
1999-08-04  0:00     ` Brian Rogoff
1999-08-05  0:00       ` Jean-Pierre Rosen
1999-08-05  0:00         ` adam
1999-08-05  0:00           ` Robert Dewar
1999-08-05  0:00             ` What is a Display ? (was: Subverting 'Access for Sub-programs) Larry Kilgallen
1999-08-05  0:00               ` Hyman Rosen
1999-08-06  0:00                 ` Robert Dewar
1999-08-06  0:00               ` Robert Dewar
1999-08-05  0:00           ` Subverting 'Access for Sub-programs adam
1999-08-06  0:00             ` Robert A Duff
1999-08-06  0:00               ` adam
1999-08-09  0:00                 ` Mark Biggar
1999-08-09  0:00                 ` Robert A Duff
1999-08-05  0:00         ` Robert A Duff
1999-08-05  0:00           ` Robert Dewar
1999-08-05  0:00           ` Brian Rogoff
1999-08-06  0:00             ` Robert Dewar
1999-08-09  0:00               ` Tucker Taft
1999-08-10  0:00                 ` Robert Dewar
1999-08-11  0:00                   ` Dmitry A. Kazakov
1999-08-11  0:00                     ` Richard D Riehle
1999-08-11  0:00                     ` Robert Dewar
1999-08-12  0:00                       ` Dmitry A. Kazakov
1999-08-14  0:00                         ` Robert Dewar
1999-08-16  0:00                           ` Dmitry A. Kazakov
1999-08-11  0:00                   ` Robert A Duff
1999-08-11  0:00                     ` Robert Dewar
1999-08-11  0:00                   ` Tucker Taft
1999-08-13  0:00                     ` Robert Dewar
1999-08-13  0:00                       ` Brian Rogoff
1999-08-13  0:00                     ` Robert Dewar
1999-08-05  0:00           ` tmoran
1999-08-06  0:00             ` Robert A Duff
1999-08-06  0:00         ` Brian Rogoff
1999-08-07  0:00           ` Gautier
1999-08-05  0:00     ` Robert A Duff
1999-08-05  0:00       ` Robert Dewar
1999-08-05  0:00         ` Brian Rogoff
1999-08-05  0:00   ` Steve Quinlan

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