{ XEmacs: This file contains Pascal source code; use -*- text -*- mode. } { Procedure parameters can be procedures with procedure parameters John David Stone Department of Mathematics and Computer Science Grinnell College stone@cs.grinnell.edu created January 31, 2003 last revised January 31, 2003 } { This program refutes a claim that John Mitchell makes in the first edition of his book _Concepts in programming languages_ (Cambridge, United Kingdom: Cambridge University Press, 2003; ISBN 0-521-78098-5): A restriction that made Pascal simpler than Algol 68 was that procedure parameters could not be procedures with procedure parameters. More specifically, in Pascal syntax, procedures of the form procedure DoSomething( j, k : integer ); procedure DoSomething( procedure P(i:integer); j,k,: integer); are allowed. The first is a procedure with integer parameters, and the second is a procedure whose parameter is a procedure with integer parameters. However, a procedure of the form procedure NotAllowed( procedure MyProc( procedure P(i:integer))); with a procedure parameter that has a procedure parameter, is _not_ allowed. (The quotation is from page 98.) In early versions of Pascal, at least through the second edition of the _Pascal User Manual and Report_, procedure parameters were not accompanied by formal parameter lists at all, but there was nothing to prohibit implementers from supporting procedures accepting arguments that were themselves procedures accepting arguments that were likewise procedures accepting arguments. ANSI and ISO Standard Pascal, however, have always required conforming Pascal processors to accept such procedures. This Standard Pascal program demonstrates that conforming implementations accept the construction that Mitchell says is forbidden. Here's a transcript of the compilation and execution of this program under the GNU Pascal compiler, version 20010623: $ gpc -o refutation refutation.p $ ./refutation I am _too_ allowed! Here is my argument to prove it: 42 } program Refutation (output); { The First procedure calls a given integer-accepting procedure, giving it the argument 42. } procedure First (procedure IntegerAcceptor (dummy: integer)); begin IntegerAcceptor (42) end; { The NotAllowed procedure calls a given procedure-accepting procedure, giving it as argument the locally-defined procedure Second. (The Second procedure could also be defined globally.) I've preserved Mitchell's header exactly. } procedure NotAllowed (procedure MyProc (procedure P (i: integer))); { The Second procedure takes an integer argument and writes it out, with appropriate commentary. } procedure Second (Scribend: integer); begin writeln ('I am _too_ allowed!'); writeln ('Here is my argument to prove it: ', Scribend : 1) end; begin {procedure NotAllowed} MyProc (Second) end; { The main program simply invokes NotAllowed, giving it First as the procedure-accepting procedure that it needs to do its job. } begin {main program} NotAllowed (First) end.