* 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 ` (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 1999-08-03 0:00 ` tmoran @ 1999-08-03 0:00 ` Steve Doiel 1999-08-03 0:00 ` Michael F. Yoder ` (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 1999-08-03 0:00 ` tmoran 1999-08-03 0:00 ` Steve Doiel @ 1999-08-03 0:00 ` Michael F. Yoder 1999-08-03 0:00 ` David C. Hoos, Sr. ` (4 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 ` Michael F. Yoder @ 1999-08-03 0:00 ` David C. Hoos, Sr. 1999-08-05 0:00 ` Robert A Duff 1999-08-03 0:00 ` Brian Rogoff ` (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 ` 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-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 ` Brian Rogoff 1999-08-03 0:00 ` Ted Dennison ` (2 subsequent siblings) 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 ` (4 preceding siblings ...) 1999-08-03 0:00 ` Brian Rogoff @ 1999-08-03 0:00 ` Ted Dennison 1999-08-04 0:00 ` Anton Gibbs 1999-08-04 0:00 ` Robert Dewar 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 ` (5 preceding siblings ...) 1999-08-03 0:00 ` Ted Dennison @ 1999-08-04 0:00 ` Anton Gibbs 1999-08-04 0:00 ` Jean-Pierre Rosen ` (2 more replies) 1999-08-04 0:00 ` Robert Dewar 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 ` Anton Gibbs @ 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-04 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-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 ` 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-05 0:00 ` Jean-Pierre Rosen @ 1999-08-05 0:00 ` adam 1999-08-05 0:00 ` adam 1999-08-05 0:00 ` Robert Dewar 1999-08-05 0:00 ` Subverting 'Access for Sub-programs 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 ` adam @ 1999-08-05 0:00 ` adam 1999-08-06 0:00 ` Robert A Duff 1999-08-05 0:00 ` Robert Dewar 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 ` 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 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-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 ` 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-05 0:00 ` adam 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 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
* 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: 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: 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: 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: 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 ` Brian Rogoff ` (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 ` Subverting 'Access for Sub-programs Robert A Duff @ 1999-08-05 0:00 ` Brian Rogoff 1999-08-06 0:00 ` Robert Dewar 1999-08-05 0:00 ` tmoran 1999-08-05 0:00 ` Robert Dewar 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 ` 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-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-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-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 ` Tucker Taft 1999-08-11 0:00 ` Robert A Duff 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 ` 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-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-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-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
* 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 ` Tucker Taft 1999-08-13 0:00 ` Robert Dewar 1999-08-13 0:00 ` Robert Dewar 1999-08-11 0:00 ` Robert A Duff 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 ` 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-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-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-10 0:00 ` Robert Dewar 1999-08-11 0:00 ` Dmitry A. Kazakov 1999-08-11 0:00 ` Tucker Taft @ 1999-08-11 0:00 ` Robert A Duff 1999-08-11 0:00 ` Robert Dewar 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-05 0:00 ` Subverting 'Access for Sub-programs Robert A Duff 1999-08-05 0:00 ` Brian Rogoff @ 1999-08-05 0:00 ` tmoran 1999-08-06 0:00 ` Robert A Duff 1999-08-05 0:00 ` Robert Dewar 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 ` 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 Robert A Duff 1999-08-05 0:00 ` Brian Rogoff 1999-08-05 0:00 ` tmoran @ 1999-08-05 0:00 ` Robert Dewar 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 ` Jean-Pierre Rosen 1999-08-05 0:00 ` adam 1999-08-05 0:00 ` Subverting 'Access for Sub-programs 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: 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-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 ` 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
* 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-04 0:00 ` Anton Gibbs 1999-08-04 0:00 ` Jean-Pierre Rosen @ 1999-08-04 0:00 ` Robert A Duff 1999-08-04 0:00 ` Brian Rogoff 1999-08-05 0:00 ` Anton Gibbs 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 ` 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-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-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-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 ` 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 ` 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 ` 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-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-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-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-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-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-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 ` Anton Gibbs 1999-08-04 0:00 ` Jean-Pierre Rosen 1999-08-04 0:00 ` Robert A Duff @ 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: 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 ` Anton Gibbs @ 1999-08-04 0:00 ` Robert Dewar 1999-08-04 0:00 ` Robert A Duff 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 ` 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 ` 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
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 ` Michael F. Yoder 1999-08-03 0:00 ` David C. Hoos, Sr. 1999-08-05 0:00 ` Robert A Duff 1999-08-03 0:00 ` Brian Rogoff 1999-08-03 0:00 ` Ted Dennison 1999-08-04 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 ` 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 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 Robert A Duff 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 ` 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-11 0:00 ` Robert A Duff 1999-08-11 0:00 ` Robert Dewar 1999-08-05 0:00 ` tmoran 1999-08-06 0:00 ` Robert A Duff 1999-08-05 0:00 ` Robert Dewar 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-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-05 0:00 ` Steve Quinlan 1999-08-04 0:00 ` Robert Dewar 1999-08-04 0:00 ` Robert A Duff 1999-08-04 0:00 ` Robert Dewar
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox