* Procedure/function parameters @ 1986-07-15 17:46 andy 1986-07-19 19:46 ` richw 0 siblings, 1 reply; 3+ messages in thread From: andy @ 1986-07-15 17:46 UTC (permalink / raw) Forgive my pascal-eze, but the following partial program is quite difficult to implement in Ada(TM) without drastic changes. Generics don't work because both top level procedures have state; reinstantiating either loses that state. Passing a tag that says which procedure to call (the enumeration scheme) doesn't work; the procedures being passed are not visible to the called procedure (and besides, they refer to variables of private types that the called procedure shouldn't know about). Notice how simple the procedure parameter solution is. (I reused names to discourage Ada implementations that change the scope of various names. A real program might use distinct names but still want to maintain separate scopes.) I recently wrote a compiler where I used procedure parameters extensively because they allowed me to maintain local state. Without this local state, the program would not have been understandable. procedure a (procedure b (procedure c)); type foo : <something>; var bar : foo; procedure c; begin {c} <manipulate bar> end; {c} begin {a} <init bar> b(c); <manipulate bar> end; {a} procedure b; {intential name reuse throughout} type foo : <something>; var bar : foo; procedure c (procedure a); begin {c} a; <manipulate bar> end; {c} begin {b} <init bar> a(c); <manipulate bar> end; {b} -andy decwrl!glacier!shasta!andy andy@sushi.stanford.edu ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Procedure/function parameters 1986-07-15 17:46 Procedure/function parameters andy @ 1986-07-19 19:46 ` richw 1986-07-22 0:31 ` andy 0 siblings, 1 reply; 3+ messages in thread From: richw @ 1986-07-19 19:46 UTC (permalink / raw) First of all, I'd rather not comment about the style of programming you've used in your example -- I personally find it to be hard to follow, but I'd rather discuss a MUCH more important issue which your example touches on... >> ... Passing a tag that says which procedure to >> call (the enumeration scheme) doesn't work; the procedures being >> passed are not visible to the called procedure (and besides, they >> refer to variables of private types that the called procedure >> shouldn't know about). You're right! The enumeration scheme does not work in this case -- AND FOR VERY GOOD REASON! The enumeration method fails, as you say, because of scoping limitations -- HOWEVER, those limitations come in handy, as Robert Firth alluded to in an earlier posting: procedure passing in languages which include nesting of procedure definitions can lead to very nasty consequences... >> Procedure variables can create a loophole in the scoping >> structure in the same way that reference variables can: it is >> possible to assign to a variable of greater extent a value of >> smaller extent, and hence access via the variable an object that >> no longer exists. There is no good way reliably to guard >> against this at compile time, for which reason some people >> dislike procedure and reference variables.... >> -- Robert Firth When I first read this, I had some trouble imagining what he meant, but then I managed to come up with a small example: package P is type One_Argument_Procedure is procedure (i : in Integer); -- The above is not legal Ada, but you know what I mean function A return One_Argument_Procedure; end P; package body P is function A return One_Argument_Procedure is local_variable : Integer; procedure Local_Proc (i : in Integer) is begin local_variable := i; end; begin return Local_Proc; end A; end P; The question is: What in the WORLD happens when someone tries to call the result of function A? You don't REALLY want to be able to modify the stack-frame of a procedure that has ALREADY RETURNED, now do you? ESPECIALLY since by the time you call that result of function A, there might be other data in the stack which has NOTHING to do with "local_variable". (You C programmers out there -- ever been bitten by this sort of bug when you return a pointer to a variable in the stack? Damn hard to track down, isn't it?) This illustrates that, if pointers to subprograms were added to Ada, only pointers to "outer" or "first level" subprograms could be valid subprogram pointers. The price that Ada would pay if pointers to nested procedures COULD be used would be a price in safety and program correctness -- one of Ada's MAJOR design goals was to provide a safe language. So, in order for you counter-example to be used as an argument for adding procedure passing to Ada, one must concede that Ada would also become less safe. Oh well... -- Rich Wagner ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Procedure/function parameters 1986-07-19 19:46 ` richw @ 1986-07-22 0:31 ` andy 0 siblings, 0 replies; 3+ messages in thread From: andy @ 1986-07-22 0:31 UTC (permalink / raw) In article <4700072@ada-uts> richw@ada-uts writes: [I sketched a program that illustrated how procedure parameters make it possible to maintain separate scopes for things that should be separate, unlike the enumeration method. In his reply, he wrote a program where one procedure returns a local procedure that will modify a local variable of the original procedure if it is ever called. He then concludes with:] >The question is: What in the WORLD happens when someone tries to >call the result of function A? You don't REALLY want to be able to >modify the stack-frame of a procedure that has ALREADY RETURNED, now >do you? ESPECIALLY since by the time you call that result of function >A, there might be other data in the stack which has NOTHING to do >with "local_variable". (You C programmers out there -- ever been >bitten by this sort of bug when you return a pointer to a variable >in the stack? Damn hard to track down, isn't it?) > >This illustrates that, if pointers to subprograms were added to Ada, >only pointers to "outer" or "first level" subprograms could be valid >subprogram pointers. The price that Ada would pay if pointers to >nested procedures COULD be used would be a price in safety and program >correctness -- one of Ada's MAJOR design goals was to provide a safe >language. So, in order for you counter-example to be used as an >argument for adding procedure passing to Ada, one must concede that >Ada would also become less safe. Oh well... > >-- Rich Wagner Wrong conclusion. If a language allows the program you describe then any implementation that behaves the way you're worried about is wrong. (In C, returning a pointer to a variable on the stack is an error. C isn't required to detect this error, but C isn't an example of a safe language.) If a language makes it possible to RETURN procedures, then an implementation must be able to heap-allocate activation records. (Note the difference between "be able to" and "always".) Some Extended Pascal dialects allow procedures as PARAMETERS, but not values (you can't put them in records or variables); their implementations can stack-allocate activation records without running into the problem you describe. If the language also requires proper declarations of these parameters, the language will be type-safe. If you've written large programs, you know how important it is to maintain the appropriate scope, as defined by the problem. That isn't an issue in small programs. (Ada is supposed to be good for large programs ....) BTW - there are languages where a procedure can return multiple times. Some of them even allow stack-allocation of activation records; you just have to be careful when you pop. -andy decwrl!glacier!shasta!andy andy@sushi.stanford.edu ps - I think it is bad style to use scoping that is wider than necessary. Procedure as parameters (and as values) are one tool to help me; you can use all globals if you prefer. ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~1986-07-22 0:31 UTC | newest] Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1986-07-15 17:46 Procedure/function parameters andy 1986-07-19 19:46 ` richw 1986-07-22 0:31 ` andy
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox