[comp.lang.misc] Re^4: Closures

kend@data.UUCP (Ken Dickey) (01/24/91)

kers@hplb.hpl.hp.com (Chris Dollin) writes:


>Ken Dickey writes:

>   ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:

>   >The only surviving language I know of that implements a proper
>   >closure facility is POP-11. Some LISP hackers seem to think they've got
>   >closures too, but they haven't--all they've got is an almost-as-useful
>   >kludge that requires call frames to be allocated on the heap.

>   Try Scheme and Common Lisp.  There are some very good compilers in
>   both camps which typically use stack frames and allocate only on the
>   heap where needed.  Note that closures which may be captured (e.g. in
>   global variables) are required to be heap allocated--or you don't have
>   the power of full closures.

>Ken (and others) seem to have fallen into the accidental terminological trap
>that Lawrence has set. In Pop, the term "closure" has traditionally meant a
>procedure created by partially applying some given to procedure to some
>collection of arguments.

I must clain ignorance of Pop, but in common usage [e.g. see (1), (2),
(3)], a closure is called such because it captures free variables by
"closing over" the environment at time of creation.  This differs from
currying [see (1), (3)] which seems to be what you mean by "closure".

Again, my viewpoint comes from literature in lambda calculus and
denotational semantics.  Are there references in the general
literature which support your definition?


-Ken Dickey			kend@data.uucp
---------------------------------------------------------

(1) Stoy: "Denotational Semantics: The Scott-Strachey Approach to
Programming Language Theory", MIT Press, 1977.

(2) Schmidt: "Denotational Semantics" A Methodology for Language
Design", Allyn and Bacon, 1986.

(3) Barendregt: "The Lambda Calculus, its Syntax and Semantics",
North-Holland, 1981.

kers@hplb.hpl.hp.com (Chris Dollin) (01/25/91)

Ken Dickey writes (following up on my earlier posting):

   >Ken (and others) seem to have fallen into the accidental terminological trap
   >that Lawrence has set. In Pop, the term "closure" has traditionally meant a
   >procedure created by partially applying some given to procedure to some
   >collection of arguments.

   I must clain ignorance of Pop, but in common usage [e.g. see (1), (2),
   (3)], a closure is called such because it captures free variables by
   "closing over" the environment at time of creation.  This differs from
   currying [see (1), (3)] which seems to be what you mean by "closure".

   Again, my viewpoint comes from literature in lambda calculus and
   denotational semantics.  Are there references in the general
   literature which support your definition?

I'm sorry, I didn't make myself clear. When I said "In Pop, the term ... " I
meant "in the existing Pop[2..11] communities" that the term closure has been
used that way. It is an idiosyncatic use, it is not the way the term is used
in other programming languages (in particular, Lisp), and it is indeed like
currying [*1]. 

I had intended to avoid confusion by pointing out that Lawrence (who appears to
be a Pop programmer or to have been exposed to it at some point) was using
"closure" in a sense different to most other readers of c.l.m. I'm sorry to
have caused any confusion myself ....

[*1] Apart from the fact that Pop closures have to be explicit (ie, making a
closure is syntactically different from applying the function - in fact it is
implemented by calling the system function "consclosure" with the function to
be closed and the arguments to be frozen in) and currying works left-to-right,
Pop partial applications working right-to-left.
--

Regards, Kers.      | "You're better off  not dreaming of  the things to come;
Caravan:            | Dreams  are always ending  far too soon."

sfk@otter.hpl.hp.com (Steve Knight) (01/25/91)

Ken writes:
> I must claim ignorance of Pop, but in common usage [...]
> a closure is called such because it captures free variables by
> "closing over" the environment at time of creation.  This differs from
> currying [see (1), (3)] which seems to be what you mean by "closure".
  ^^^^^^^^
Partial application, not currying, of course.  I presume this is a slip of
the fingers.

Yes, partial application can be used to implement a full-closure mechanism.
It is fairly easy to transform (nested) procedures so that they have no
free-variables EXCEPT for global-variables -- this is akin to lambda-lifting
but works equally well in imperative languages.  This transformation assumes
partial application works, of course.

Having transformed a program into this form, all closure-forming
operations are trivially tackled by partial application, since formal
parameter lists are the only environments that need to be closed over.  This
resolves the conflict of terminology.

> Again, my viewpoint comes from literature in lambda calculus and
> denotational semantics.  Are there references in the general
> literature which support your definition?

As you can see, the same ones :-)

Steve

jeff@aiai.ed.ac.uk (Jeff Dalton) (01/29/91)

In article <2400030@otter.hpl.hp.com> sfk@otter.hpl.hp.com (Steve Knight) writes:
>Yes, partial application can be used to implement a full-closure mechanism.

And so can a variety of other mechanisms.

>It is fairly easy to transform (nested) procedures so that they have no
>free-variables EXCEPT for global-variables -- this is akin to lambda-lifting
>but works equally well in imperative languages.  This transformation assumes
>partial application works, of course.

It also assumes that assignment to a frozen formal works (persists
across calls) w/o some additional translformation.  It doesn't, at
least not in Pop-11 as it was in '84 or so.

>Having transformed a program into this form, all closure-forming
>operations are trivially tackled by partial application, 

And just imagine yourself transforming your program into this form
so that you can trivially tackle some problem.