{ 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.