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!mnetor!uunet!husc6!cmcl2!rutgers!ames!sdcsvax!ucbvax!VLSI.JPL.NASA.GOV!larry From: larry@VLSI.JPL.NASA.GOV Newsgroups: comp.lang.ada Subject: Firth's "Procedures as Parameters" Message-ID: <870922174711.047@VLSI.JPL.NASA.GOV> Date: Tue, 22-Sep-87 20:47:10 EDT Article-I.D.: VLSI.870922174711.047 Posted: Tue Sep 22 20:47:10 1987 Date-Received: Fri, 25-Sep-87 01:22:15 EDT Sender: daemon@ucbvax.BERKELEY.EDU Organization: The ARPA Internet List-Id: -- -- Almost 30 requests have been received so far asking for the following, -- so I'm sending it out net-wide rather than to individuals. Larry Recent posts have raised the issue of procedures as parameters to other procedures. First, this does not impair compile-time type checking. Parametric procedures cannot be type checked in Algol-60 or Pascal because the language does not require that their own parameters be speciofied. Naturally, if you don't specify the formals, you can't check the actuals when the parametric procedure is called, and I really cannot understand why it needs 30 pages of formalism to establish that. However, this can be fixed simply by changing the language to require full specification of parametric procedures. I did that when I wrote an Algol-60 compiler, and it gave no trouble. In a language such as Algol-68 or RTL/2 the task is harder, since it is possible to define reflexive types, such as a procedure that takes as a parameter another procedure of its own type, or a STRUCT that contains a REF to its own type. In these cases, the type checking algorithm is recursive, and to avoid infinite regress must check for reflexive references; the usual way to do this is by an Ariadne thread. Secondly, adding parametric procedures, or even procedure variables, does not greatly increase the complexity of a language. The implementation must construct a runtime value that designates a procedure; this usually consists of a component that points to the code and another that identifies the execution environment (eg the end of a static chain). This latter component can be avoided if one restricts the values of procedure variables to outer-level procedures, as Modula-2 does, but in my opinion the loss to the user far outweighs the gain to the implementor. 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. Algol-68 has this problem; Ada avoids it by not permitting a pointer to a local variable. Of course, the problem does not arise if parametric procedures are allowed, but procedure variables aren't. Finally, procedure variables in Ada. They aren't there, and I miss them. There are three ways of coding around the problem, but it must be admitted that they are bad ways, and not a sensible substitute for the real thing. (a) use tasks. The English idiom to describe this is "too clever by half" (b) use an enumeration type and a CASE statement as a dispatch list. This fails because it requires the "actuals" to be known when the procedure with the "formal" is written, which (again in my opinion) is an unacceptable feature. (c) cheat by passing 'ADDRESS of the actual and writing a magic CALL procedure. You need a different CALL for each signature, to get the types right, and you lose the type checking. Moreover, you probably can't get hold of the environment of the actual and so can pass only outer-level procedures with any chance of it working. A fourth solution is to use generics and hope that the implementation will indeed share code. Why are procedure variables or parameters missing? They are forbidden by the Steelman requirement. Now, in some cases Ada diverges from the requirement (eg in providing approximate fixed-point). But the original type model was designed without procedures as first-class objects, and to change that would have been so great an upheaval that it never seemed feasible. Some of us urged it nevertheless, especially after tasks were made (almost) first-class objects. But why was the requirement written that way? The hidden reason is that it was believed that programs in the resulting language would be easier mechanically to verify, if procedures did not have execution-time variability. I happen to think this a bad reason, because I believe our program verification techniques are so inadequate that, if we restricted ourselves to things we could verify, we would be able to write very little useful code. There are few cases where parametric procedures are required, but in those cases, they are indispendsible, and the language is poorer without them. Yes, an issue for the 1988 revision. Robert Firth