From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!caip!topaz!uwvax!husc6!harvard!adelie!mirror!gabriel!ada-uts!richw From: richw@ada-uts Newsgroups: net.lang.ada Subject: Re: Procedure/function parameters Message-ID: <4700072@ada-uts> Date: Sat, 19-Jul-86 15:46:00 EDT Article-I.D.: ada-uts.4700072 Posted: Sat Jul 19 15:46:00 1986 Date-Received: Mon, 21-Jul-86 06:41:49 EDT References: <679@Shasta.STANFORD.EDU> Nf-ID: #R:Shasta.STANFORD.EDU:-67900:ada-uts:4700072:37777777600:3009 Nf-From: ada-uts!richw Jul 19 15:46:00 1986 List-Id: 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