Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!tut.cis.ohio-state.edu!ucbvax!hplabs!otter.hpl.hp.com!hpltoad!cdollin!kers From: kers@hplb.hpl.hp.com (Chris Dollin) Newsgroups: comp.lang.misc Subject: Re: Re^2: Closures (was Re: class-sic.) Message-ID: Date: 22 Jan 91 08:28:50 GMT References: <20058@yunexus.YorkU.CA> <27942:Jan902:20:0791@kramden.acf.nyu.edu> <27770.278aef90@kuhub.cc.ukans.edu> <22345:Jan1021:30:4591@ Sender: news@hplb.hpl.hp.com (Usenet News Administrator) Organization: Hewlett-Packard Laboratories, Bristol, UK. Lines: 57 In-Reply-To: kend@data.UUCP's message of 21 Jan 91 16:45:56 GMT Nntp-Posting-Host: cdollin.hpl.hp.com 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. Partial application has a concrete syntax like a decorated procedure call (see below). As a (trivial) example, if we define pr_them( x, y ); lvars x, y; pr( x ); pr( y ) enddefine; then |pr_them(% 42 %)| is a procedure that, when applied to some argument A, will print A and then print 42 - note that the frozen argument 42 is the *rightmost* of the original argument list (due to Pop's open-stack nature). Lisp hasn't got closures (partial applications), although it does have closures (lexically-scoped functions exported out of their binding environment). In Pop, closures are used to *implement* closures .... Partial applications are dead useful. I wouldn't be without them - where you use them, they're a lot handier than having to write out a suitable lambda-expression. They do induce a tendency to organise argument lists in a particular way - with the most "freezable" arguments at the right - which may or may not be a good thing. As a sidenote to discussions elsewhere on function composition, I offer define run_them( f, g ); lvars f, g; f(); g() enddefine; Now |run_them(% F, G %)| is the composition of |F| and |G|. (Arguments? Oh, they're on the stack. F takes its args of the stack and puts its results back on; ditto G. I wouldn't be without the open stack, either.) -- Regards, Kers. | "You're better off not dreaming of the things to come; Caravan: | Dreams are always ending far too soon."