kers@hplb.hpl.hp.com (Chris Dollin) (01/22/91)
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."
new@ee.udel.edu (Darren New) (01/23/91)
In article <KERS.91Jan22082850@cdollin.hpl.hp.com> kers@hplb.hpl.hp.com (Chris Dollin) writes: >They [POP-11 closures] 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. Actually, I don't know that it is the closures doing this. FORTH has an "open stack" as I understand you to use the term, and "more freezable" arguments are also at the right. For example, x y ! (! is the assignment operator) will assign the value x to the variable y. I.e., a:=5 --> 5 a ! Here, the "a" comes second because you more often know statically what variable you want to store into than you know what value you want stored. That is, you more often have a procedure called "store into a" than you do one called "store a 5". Contrast this with PostScript code, where the storage operator (def) is often preceded by an exch (exchange) because the name of the value to be stored is coded into the procedure but the value is passed in. (I think this was done in order that procedure definitions had the name preceding the block of code.) Anyway, I think it is more the LIFO nature of the stack than the closure mechanism that makes "freezable" arguments on the right, unless you are implying that : storexyz xyz ! ; is a partial application of the ! function. -- Darren -- --- Darren New --- Grad Student --- CIS --- Univ. of Delaware --- ----- Network Protocols, Graphics, Programming Languages, Formal Description Techniques (esp. Estelle), Coffee, Amigas ----- =+=+=+ Let GROPE be an N-tuple where ... +=+=+=