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