[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: a brief introduction to "closures" for "uneducated" C hackers



John Clonts writes:

 > I have a vague recollection that Pascal allowed nested functions-- but I
 > don't recall how or if it dealt with this.  Does anyone here know?

        In Standard Pascal, you can't return a function from another
function, but you can pass one in as a parameter to a function, so the
problem does arise in that direction.  The solution was indeed to use a
closure.  The Turbo Pascal implementers never got the hang of this, which
is why their mechanism for passing procedures and functions as arguments is
non-standard -- they used the pointer-passing technique that Matthias was
ridiculing.

        This property of Pascal was exploited, for instance, in
R. D. Tennent's _Principles of programming languages_ (Englewood Cliffs,
New Jersey: Prentice/Hall International, 1981), to construct classes.  He
gives only a schematic example (see pages 143-144), but here's a complete
Pascal program that demonstrates the technique:

program demo (output);
var i: integer;

  procedure random(seed: integer;
                   procedure inner(procedure draw(var x: real)));
    const m = 25173;
    const d = 65536;
    const i = 13849;
    var a: integer;

    procedure draw (var x: real);
    begin
      a := (a*m + i) mod d;
      x := a/d;
    end;

  begin {procedure random}
    a := seed mod d;
    inner(draw)  {The value passed here is a closure
                  that includes the binding for a.}
  end;

  procedure use(procedure draw(var x: real));
    var r: real;

  begin {procedure use}
    draw(r);  {update r to the next random number}
    writeln('After one draw, r = ', r:1:4);
    draw(r);
    writeln('After another draw, r = ', r:1:4)
  end;

begin {program demo}
  random(389, use);  {create an object of the random-number generator class}
  random(471, use)   {create another}
end.