From: Dave Roberts
Subject: "Staggering power of closures..."
Date: 
Message-ID: <3uF9c.25112$K91.72067@attbi_s02>
I managed to miss the great C vs. Lisp speed challenge earlier this month
when I was traveling (titled "Re: off-topic: open challenge to Christian
Lynbeck"). In the course of going back and reading that thread (good job,
guys, BTW! I learned a whole lot about Lisp optimization that I never would
have learned otherwise), I found a posting by Matthew Danish where he says:

> Perhaps one of the more difficult parts of learning Lisp from a C
> background is the realization of the power of the constructs, and
> acquiring the knowledge to know where and how to use them.  A good
> example of this is closures.  When I explain the concept to a typical C
> programmer, they often say something like ``oh, you mean static
> variables in functions'' or ``so what?''  Unless the person is versed in
> computability theory (and/or the lambda calculus) it is difficult for
> them to comprehend at first the staggering power of such a simple idea.
> The concept of a closure is a feature which is almost universal to
> high-level languages, and when you understand it is hard to imagine
> getting by without it.

This struck me. I was a C programmer, learned a whole lot of Java, and am
now trying to learn a whole lot of CL. As I have approached the language,
everybody keeps talking about closures as being one of the mind-blowing
pieces of it. Perhaps that's true when you're coming strictly from C, but I
find that I'm not as blown away with them after playing in the OOP world
for a while (C++, Java, etc. Yes, I know those object models have
issues--that's why I'm learning CL now). Whenever I see a closure, I simply
see an object. It's one or more functions connected to a local environment
that holds some private bindings.

In reading Paul Graham's papers on Lisp, I was struck that he was actually a
bit negative on OOP (CLOS, specifically), because he thought that most
everything you needed could be done with functions and closures.

So the question is, am I missing something staggering about closures, or
have I just grasped the idea so well before that I'm missing it now? Is
there something with closures that can't be done with objects in a Java
world, for instance? If so, what?

Note that I would actually rank first-class functions and powerful macros as
more staggering than closures as I have been learning CL. My point isn't
that CL doesn't have staggering features or even that closures aren't one
of them if you're coming from a world without objects. My question is
really, what am I missing about closures, if anything?

-- 
Dave Roberts
·············@re-move.droberts.com

From: Kenny Tilton
Subject: Matthew Danish must never say "stagger" again [was Re: "Staggering power of closures..."]
Date: 
Message-ID: <Y0H9c.12476$DV6.7190@twister.nyc.rr.com>
Is it Ground Hog day?

:)

kenzo

Dave Roberts wrote:
> I managed to miss the great C vs. Lisp speed challenge earlier this month
> when I was traveling (titled "Re: off-topic: open challenge to Christian
> Lynbeck"). In the course of going back and reading that thread (good job,
> guys, BTW! I learned a whole lot about Lisp optimization that I never would
> have learned otherwise), I found a posting by Matthew Danish where he says:
> 
> 
>>Perhaps one of the more difficult parts of learning Lisp from a C
>>background is the realization of the power of the constructs, and
>>acquiring the knowledge to know where and how to use them.  A good
>>example of this is closures.  When I explain the concept to a typical C
>>programmer, they often say something like ``oh, you mean static
>>variables in functions'' or ``so what?''  Unless the person is versed in
>>computability theory (and/or the lambda calculus) it is difficult for
>>them to comprehend at first the staggering power of such a simple idea.
>>The concept of a closure is a feature which is almost universal to
>>high-level languages, and when you understand it is hard to imagine
>>getting by without it.
> 
> 
> This struck me. I was a C programmer, learned a whole lot of Java, and am
> now trying to learn a whole lot of CL. As I have approached the language,
> everybody keeps talking about closures as being one of the mind-blowing
> pieces of it. Perhaps that's true when you're coming strictly from C, but I
> find that I'm not as blown away with them after playing in the OOP world
> for a while (C++, Java, etc. Yes, I know those object models have
> issues--that's why I'm learning CL now). Whenever I see a closure, I simply
> see an object. It's one or more functions connected to a local environment
> that holds some private bindings.
> 
> In reading Paul Graham's papers on Lisp, I was struck that he was actually a
> bit negative on OOP (CLOS, specifically), because he thought that most
> everything you needed could be done with functions and closures.
> 
> So the question is, am I missing something staggering about closures, or
> have I just grasped the idea so well before that I'm missing it now? Is
> there something with closures that can't be done with objects in a Java
> world, for instance? If so, what?
> 
> Note that I would actually rank first-class functions and powerful macros as
> more staggering than closures as I have been learning CL. My point isn't
> that CL doesn't have staggering features or even that closures aren't one
> of them if you're coming from a world without objects. My question is
> really, what am I missing about closures, if anything?
> 

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Dave Roberts
Subject: Re: Matthew Danish must never say "stagger" again [was Re: "Staggering power of closures..."]
Date: 
Message-ID: <VFH9c.25616$w54.166903@attbi_s01>
Kenny Tilton wrote:

> Is it Ground Hog day?
> 
> :)
> 
> kenzo

Sorry, did we already cover this? I must have missed that, too. Tell me how
it went. ;-)

-- 
Dave Roberts
·············@re-move.droberts.com
From: Kenny Tilton
Subject: Re: Matthew Danish must never say "stagger" again [was Re: "Staggering power of closures..."]
Date: 
Message-ID: <FEI9c.12491$DV6.7345@twister.nyc.rr.com>
Dave Roberts wrote:
> Kenny Tilton wrote:
> 
> 
>>Is it Ground Hog day?
>>
>>:)
>>
>>kenzo
> 
> 
> Sorry, did we already cover this? I must have missed that, too. Tell me how
> it went. ;-)

If this does not work:

 
http://www.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=Wm31c.3307%24Wo2.2799%40twister.nyc.rr.com&rnum=2&prev=/groups%3Fq%3Dstagger%2Bgroup:comp.lang.lisp%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26selm%3DWm31c.3307%2524Wo2.2799%2540twister.nyc.rr.com%26rnum%3D2

..just Google groups on "stagger" in comp.lang.lisp. The opening volley 
went:

Jacek Generowicz wrote:
> Matthew Danish <·······@andrew.cmu.edu> writes:
> 
>> Perhaps one of the more difficult parts of learning Lisp from a C
>> background is the realization of the power of the constructs, and
>> acquiring the knowledge to know where and how to use them.  A good
>> example of this is closures.  When I explain the concept to a typical C
>> programmer, they often say something like ``oh, you mean static
>> variables in functions'' or ``so what?''  Unless the person is versed in
>> computability theory (and/or the lambda calculus) it is difficult for
>> them to comprehend at first the staggering power of such a simple idea.
> 
> I've heard statements to this effect before. Now, I love closures, I
> like to believe that I understand them quite well. I find them
> natural, I frequently use them, I often get annoyed by their absence
> when using languages which don't support them (or support them badly).
> 
> Yet, I've never been tempted to call their power "staggering".

Look familiar? :) I responded:

> I am having visions of a long thread involving mostly agreement but also 
> lots of "yes, that is awesome, but not /staggering/".
> 
> This should be fun. :)

In fact, I have now christened this "The Stagger-Me Trap", a submission 
hold most recently used by Andre to paralyze the denizens of 
comp.lang.lisp over loop.

Sebastian added a nice literary cross-reference when he upgraded the 
thread subject to "The Unbearable Staggeringness of Closures". Can't top 
that.

:)

kt



-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Matthew Danish
Subject: Re: Matthew Danish must never say "stagger" again [was Re: "Staggering power of closures..."]
Date: 
Message-ID: <20040329013125.GC22619@mapcar.org>
A little bit of hyperbole goes a long way...

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Dave Roberts
Subject: Re: Matthew Danish must never say "stagger" again [was Re: "Staggering power of closures..."]
Date: 
Message-ID: <2QL9c.26884$K91.76453@attbi_s02>
Matthew Danish wrote:

> A little bit of hyperbole goes a long way...

Indeed. You're famous... at least in my book. ;-)

-- 
Dave Roberts
·············@re-move.droberts.com
From: Kenny Tilton
Subject: Re: Matthew Danish must never say "stagger" again [was Re: "Staggering power of closures..."]
Date: 
Message-ID: <P3N9c.13151$DV6.8266@twister.nyc.rr.com>
Matthew Danish wrote:

> A little bit of hyperbole goes a long way...
> 

Terrifyingly (impressively?) so. Knowing our articles are subjected to 
such incredible...uh, somehwat close scrutiny will -- no, might have an 
astonishingly -- XXXXXXXXXXXX -- noticeably chilling effect on the 
group. Group is too strong...

kt

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Sebastian Stern
Subject: Re: Matthew Danish must never say "stagger" again [was Re: "Staggering power of closures..."]
Date: 
Message-ID: <ad7d32de.0403300943.57c1873d@posting.google.com>
Kenny Tilton:
> Sebastian added a nice literary cross-reference when he upgraded the 
> thread subject to "The Unbearable Staggeringness of Closures". Can't top 
> that.

Yes, I was thinking of a book title in the back of my head, but
confused it with the wrong one.  I should have renamed the thread "A
Heartbreaking Work of Staggering Closures" instead.

http://www.amazon.com/exec/obidos/tg/detail/-/0375725784/102-9893695-9555323?v=glance

Try topping that... ;-)

-- 
Sebastian Stern

"Freedom is the freedom to say (= (+ 2 2) 4). If that is granted, all
else follows."
From: Jacek Generowicz
Subject: Re: Matthew Danish must never say "stagger" again [was Re: "Staggering power of closures..."]
Date: 
Message-ID: <tyf4qs52vzx.fsf@pcepsft001.cern.ch>
Kenny Tilton <·······@nyc.rr.com> writes:

> Dave Roberts wrote:
> > Kenny Tilton wrote:
> >
> 
> >>Is it Ground Hog day?
> >>
> >>:)
> >>
> >>kenzo
> > Sorry, did we already cover this? I must have missed that, too. Tell
> > me how
> 
> > it went. ;-)
> 
> If this does not work:
> 
>  http://www.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=Wm31c.3307%24Wo2.2799%40twister.nyc.rr.com&rnum=2&prev=/groups%3Fq%3Dstagger%2Bgroup:comp.lang.lisp%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26selm%3DWm31c.3307%2524Wo2.2799%2540twister.nyc.rr.com%26rnum%3D2
> 
> 
> ..just Google groups on "stagger" in comp.lang.lisp. The opening
> volley went:
> 
> 
> Jacek Generowicz wrote:
> > Matthew Danish <·······@andrew.cmu.edu> writes:
> >
> 
> >> Perhaps one of the more difficult parts of learning Lisp from a C
> >> background is the realization of the power of the constructs, and
> >> acquiring the knowledge to know where and how to use them.  A good
> >> example of this is closures.  When I explain the concept to a typical C
> >> programmer, they often say something like ``oh, you mean static
> >> variables in functions'' or ``so what?''  Unless the person is versed in
> >> computability theory (and/or the lambda calculus) it is difficult for
> >> them to comprehend at first the staggering power of such a simple idea.
> > I've heard statements to this effect before. Now, I love closures, I
> 
> > like to believe that I understand them quite well. I find them
> > natural, I frequently use them, I often get annoyed by their absence
> > when using languages which don't support them (or support them badly).
> > Yet, I've never been tempted to call their power "staggering".

Actually, in that thread a few people hinted at, or explicitly
mentioned continuation passing style. I think that CPS, in appropriate
situations, can be considered to be a staggering application of
closures (although maybe I'm only staggered by it because I'm not
intimately familiar with it, and hence sufficiently blase about it.)
From: Joe Marshall
Subject: Re: Matthew Danish must never say "stagger" again
Date: 
Message-ID: <lllh9ewh.fsf@comcast.net>
Jacek Generowicz <················@cern.ch> writes:

> Actually, in that thread a few people hinted at, or explicitly
> mentioned continuation passing style. I think that CPS, in appropriate
> situations, can be considered to be a staggering application of
> closures (although maybe I'm only staggered by it because I'm not
> intimately familiar with it, and hence sufficiently blase about it.)

I concur.  I claim that any language in which you cannot program in
continuation-passing style is fundamentally broken.

-- 
~jrm
From: André Thieme
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <c47e7f$6pp$1@ulric.tng.de>
Dave Roberts wrote:

> In reading Paul Graham's papers on Lisp, I was struck that he was actually a
> bit negative on OOP (CLOS, specifically), because he thought that most
> everything you needed could be done with functions and closures.

Yes, it is obvious that Graham is not a big fan of oop.
See these two quotes:

"I personally have never needed object-oriented abstractions. Common
Lisp has an enormously powerful object system and I've never used it
once. I've done a lot of things (e.g. making hash tables full of
closures) that would have required object-oriented techniques to do in
wimpier languages, but I have never had to use CLOS."
- http://www.paulgraham.com/noop.html


"With macros, closures, and run-time typing, Lisp transcends
object-oriented programming."
- http://lib1.store.vip.sc5.yahoo.com/lib/paulgraham/acl1.txt



> So the question is, am I missing something staggering about closures, or
> have I just grasped the idea so well before that I'm missing it now? Is
> there something with closures that can't be done with objects in a Java
> world, for instance? If so, what?

In Java you can simulate closures with inner classes.
They are a bit more verbose, but most of this additional code can be
generated by your ide.

And by the way, Java and C++ are turing-complete, so there is in
theory no program that you could only write with Lisp.
The question is, if you want to spend so much time for a given problem
to do it without Lisp ;)


By the way, when I confronted Paul with this question:
"So, if you never used Lisps object system... how can you know that you
can transcend it with macros, closures, and run-time typing?"

and he answered:
"Because I can *implement* oo."


Andr�
--
From: Rahul Jain
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <874qs8o3ux.fsf@nyct.net>
Andr� Thieme <······································@justmail.de> writes:

> By the way, when I confronted Paul with this question:
> "So, if you never used Lisps object system... how can you know that you
> can transcend it with macros, closures, and run-time typing?"
>
> and he answered:
> "Because I can *implement* oo."

User-definable strong types were the main thing that required specific
compiler support to implement. Of course, I can implement CLOS in C, as
part of a CL implemented in C.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Dave Roberts
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <rJH9c.26037$JO3.27392@attbi_s04>
André Thieme wrote:

> In Java you can simulate closures with inner classes.
> They are a bit more verbose, but most of this additional code can be
> generated by your ide.

Why inner classes? Why not just standard classes. That is, don't free
variables in a closure basically equate to instance fields in an object,
with instance methods taking the place of functions? If not, can you please
explain the differences?

> And by the way, Java and C++ are turing-complete, so there is in
> theory no program that you could only write with Lisp.
> The question is, if you want to spend so much time for a given problem
> to do it without Lisp ;)
> 
> By the way, when I confronted Paul with this question:
> "So, if you never used Lisps object system... how can you know that you
> can transcend it with macros, closures, and run-time typing?"
> 
> and he answered:
> "Because I can *implement* oo."

Of course. You can get there with any of these things, it's just a matter of
how many keystrokes you want to type...

-- 
Dave Roberts
·············@re-move.droberts.com
From: Rahul Jain
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <87zna0mp68.fsf@nyct.net>
Dave Roberts <·············@re-move.droberts.com> writes:

> André Thieme wrote:
>
>> In Java you can simulate closures with inner classes.
>> They are a bit more verbose, but most of this additional code can be
>> generated by your ide.
>
> Why inner classes? Why not just standard classes. That is, don't free
> variables in a closure basically equate to instance fields in an object,
> with instance methods taking the place of functions? If not, can you please
> explain the differences?

You need to keep a reference to the outer environment (the outer class)
so that when the bindings (instance variables) change values, you see
that change. Yes, you can keep the reference explicitly, but an inner
class makes it a bit easier to deal with in many cases.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Peter Seibel
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <m3fzbsipti.fsf@javamonkey.com>
Dave Roberts <·············@re-move.droberts.com> writes:

> Andr� Thieme wrote:
>
>> In Java you can simulate closures with inner classes.
>> They are a bit more verbose, but most of this additional code can be
>> generated by your ide.
>
> Why inner classes? Why not just standard classes. That is, don't free
> variables in a closure basically equate to instance fields in an object,
> with instance methods taking the place of functions? If not, can you please
> explain the differences?

The difference is mostly one of convenience. When I write:

  (defun foo (x y z things)
    (mapcar #'(lambda (thing) (frob x y thing)) things))

I don't have to think about making a class to hold the X and Y values.
And when I decide I want to change that to:

  (defun foo (x y z things)
    (mapcar #'(lambda (thing) (super-frob x y z thing)) things))

I don't have to also go edit my class definition to add a field to
hold the Z value. Inner classes, give this part of the convenience of
closures since the compiler figures out which local variables I'm
refering to and creates a class with just the right fields to hold
them and under the covers calls a constructor with the local variables
as arguments so their values can be used to initialize the fields.

The difference of course, as various folks have pointed out, is that
the instance of the inner class has a copy of the *value* not a
reference to the actual variable, so it's trickier to write the
equivalent of this:

  (defun foo (things)
    (let ((count 0))
      (values (mapcar #'(lambda (thing)
                          (when (good-p thing) (incf count))
                          (frob thing)) things)
              count)))

(The nearest translation in Java would involve making count a mutable
object such as a one-element array. Which is pretty gross and liable
to confuse the heck out of your average Java programmer.)

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Dave Roberts
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <icL9c.122542$po.812225@attbi_s52>
Peter Seibel wrote:

> The difference is mostly one of convenience. When I write:
> 
>   (defun foo (x y z things)
>     (mapcar #'(lambda (thing) (frob x y thing)) things))
> 
> I don't have to think about making a class to hold the X and Y values.
> And when I decide I want to change that to:
> 
>   (defun foo (x y z things)
>     (mapcar #'(lambda (thing) (super-frob x y z thing)) things))
> 
> I don't have to also go edit my class definition to add a field to
> hold the Z value. Inner classes, give this part of the convenience of
> closures since the compiler figures out which local variables I'm
> refering to and creates a class with just the right fields to hold
> them and under the covers calls a constructor with the local variables
> as arguments so their values can be used to initialize the fields.

Right, good point. So this is pretty nice. "Low overhead" is I guess the way
I would put it.

> The difference of course, as various folks have pointed out, is that
> the instance of the inner class has a copy of the *value* not a
> reference to the actual variable, so it's trickier to write the
> equivalent of this:
> 
>   (defun foo (things)
>     (let ((count 0))
>       (values (mapcar #'(lambda (thing)
>                           (when (good-p thing) (incf count))
>                           (frob thing)) things)
>               count)))
> 
> (The nearest translation in Java would involve making count a mutable
> object such as a one-element array. Which is pretty gross and liable
> to confuse the heck out of your average Java programmer.)

Yup. The syntax is just so much cleaner in general. I fully agree with that.
As you say, you could do it in Java, but the amount of pain goes up
substantially, which sort of steers you away from using. With Lisp, it's a
lot easier and so you're more likely to use it.

-- 
Dave Roberts
·············@re-move.droberts.com
From: Boris Schaefer
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <87smfsgi9f.fsf@qiwi.uncommon-sense.net>
* Dave Roberts <·············@re-move.droberts.com> wrote:
| 
| Yup. The syntax is just so much cleaner in general. I fully agree
| with that.  As you say, you could do it in Java, but the amount of
| pain goes up substantially, which sort of steers you away from
| using. With Lisp, it's a lot easier and so you're more likely to use
| it.

And, IMHO, if you start accepting the syntax argument, you'll see that
this is the "staggering" power of closures.  If you don't accept
syntactic arguments, you'll always be able to say: "But I can do that
in Java (C, C++, whatever) as well!"  However, as we all know, you can
implement anything in Java, although, if the pain to use a construct
exceeds a certain threshold, you probably won't do it, and thus, in
practice, you actually don't have the power to use said construct.
Working long enough, you can probably tear down a house with a hammer,
but would you say a hammer is equally powerful to a bulldozer?

-- 
·····@uncommon-sense.net - <http://www.uncommon-sense.net/>

Most of the fear that spoils our life comes from attacking difficulties
before we get to them.
		-- Dr. Frank Crane
From: Dave Roberts
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <nAX9c.30753$JO3.28995@attbi_s04>
Boris Schaefer wrote:

> * Dave Roberts <·············@re-move.droberts.com> wrote:
> | 
> | Yup. The syntax is just so much cleaner in general. I fully agree
> | with that.  As you say, you could do it in Java, but the amount of
> | pain goes up substantially, which sort of steers you away from
> | using. With Lisp, it's a lot easier and so you're more likely to use
> | it.
> 
> And, IMHO, if you start accepting the syntax argument, you'll see that
> this is the "staggering" power of closures.  If you don't accept
> syntactic arguments, you'll always be able to say: "But I can do that
> in Java (C, C++, whatever) as well!"  However, as we all know, you can
> implement anything in Java, although, if the pain to use a construct
> exceeds a certain threshold, you probably won't do it, and thus, in
> practice, you actually don't have the power to use said construct.
> Working long enough, you can probably tear down a house with a hammer,
> but would you say a hammer is equally powerful to a bulldozer?
> 

Right. Agreed fully. My original question was really about the difference
between a closure and a simple object. The answer, I guess, is that a
closure is "staggering" simply because it's like a *very* simple, very
low-overhead object, which can be created anywhere with such simple syntax.
The mechanism is just so low-overhead, but yet powerful, that it changes
the way you write programs.

Okay, I'll buy Matt's "staggering" comment.

-- 
Dave Roberts
·············@re-move.droberts.com
From: =?UTF-8?B?QW5kcsOpIFRoaWVtZQ==?=
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <c47ikd$a1c$1@ulric.tng.de>
Dave Roberts wrote:

> André Thieme wrote:
> 
> 
>>In Java you can simulate closures with inner classes.
>>They are a bit more verbose, but most of this additional code can be
>>generated by your ide.
> 
> 
> Why inner classes? Why not just standard classes. That is, don't free
> variables in a closure basically equate to instance fields in an object,
> with instance methods taking the place of functions? If not, can you please
> explain the differences?

With inner classes you can pass around code.
The "outer class" contains the environment that completely defines the
inner class.


André
--
From: Anton van Straaten
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <nwkac.5834$yN6.4365@newsread2.news.atl.earthlink.net>
Dave Roberts wrote:
> Andr� Thieme wrote:
> > And by the way, Java and C++ are turing-complete, so there is in
> > theory no program that you could only write with Lisp.
> > The question is, if you want to spend so much time for a given problem
> > to do it without Lisp ;)
> >
> > By the way, when I confronted Paul with this question:
> > "So, if you never used Lisps object system... how can you know that you
> > can transcend it with macros, closures, and run-time typing?"
> >
> > and he answered:
> > "Because I can *implement* oo."
>
> Of course. You can get there with any of these things, it's just a matter
of
> how many keystrokes you want to type...

An important point, and where Paul has got it right, is that it's actually
quite easy to implement OO - just about any kind you want - with macros &
closures.  In many systems, this may be a practical solution, although
that's subjective.

OTOH, you can't fake macros within a language, and without macros, you can't
*practically* fake lightweight closures - the results aren't lightweight.
So there's an enormous expressivity imbalance here, with the balance of
expressive power weighted strongly towards Lisp.

Put another way, the typing-of-the-extra-keystrokes is something you only
have to do in other languages.  Lisp is not just Turing-complete, it's
maximally expressive.

Anton
From: Michael Hudson
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <m3vfklw9kq.fsf@pc150.maths.bris.ac.uk>
"Anton van Straaten" <·····@appsolutions.com> writes:

> An important point, and where Paul has got it right, is that it's
> actually quite easy to implement OO - just about any kind you want -
> with macros & closures.  In many systems, this may be a practical
> solution, although that's subjective.

Actually, I think closures are a terrible way to implement objects,
beyond the 'that's neat' level.  Lack of introspection is the first
thing that comes to mind...

Cheers,
mwh

-- 
  Many of the posts you see on Usenet are actually from moths.  You
  can tell which posters they are by their attraction to the flames.
                                      -- Internet Oracularity #1279-06
From: Anton van Straaten
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <wACac.6608$yN6.6342@newsread2.news.atl.earthlink.net>
Michael Hudson <···@python.net> wrote:

> "Anton van Straaten" <·····@appsolutions.com> writes:
>
> > An important point, and where Paul has got it right, is that it's
> > actually quite easy to implement OO - just about any kind you want -
> > with macros & closures.  In many systems, this may be a practical
> > solution, although that's subjective.
>
> Actually, I think closures are a terrible way to implement objects,
> beyond the 'that's neat' level.  Lack of introspection is the first
> thing that comes to mind...

You're saying that closures don't have a built-in introspection capability,
but that's the point.

If they did, they'd have a particular kind of introspection, using a
particular mechanism, and if you wanted some other kind, you're usually out
of luck - either because the existing mechanism makes a different mechanism
impractical, or because the design of the original mechanism didn't cater
for wanting to do something different.  Perhaps the author of the language
had some subjective behavior-constraining mantra in mind, like how many ways
to do something there ought to be.

If you want objects with introspection, you can build them.  There's
certainly no problem doing that with closures.  How do you think
introspection works in any other language?  Someone implemented it.  But
most languages don't have the power to practically implement such things
within the language, so whoever implemented it fixed it for all time in the
underlying implementation language, like C.

People looking at lambda and closures from other languages tend to
misunderstand the level at which they can operate, because the languages
they're used to have no equivalent.  Lambda is as much a language designer's
tool, as it is for application programmers, and that's what Paul Graham is
referring to - because the smartest application programmers are also
language designers.

The point about closures is that they're not an enormous blob of arbitrarily
combined and pathologically coupled functionality, as objects are in most
systems.  They're a minimal construct, a minimal computational unit, an
atom.  If you doubt this, you should take a look at the formal rules for the
behavior of lambda (the closure constructor), and compare it to the formal
rules for the construct of your choice (if there even are any).

Lambda and the closures they generate are as simple as computation gets
while still being useful, which is exactly what makes them useful as a
building block.

Anton
From: Michael Hudson
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <m3lllhvtkv.fsf@pc150.maths.bris.ac.uk>
"Anton van Straaten" <·····@appsolutions.com> writes:

> Michael Hudson <···@python.net> wrote:
> 
> > "Anton van Straaten" <·····@appsolutions.com> writes:
> >
> > > An important point, and where Paul has got it right, is that it's
> > > actually quite easy to implement OO - just about any kind you want -
> > > with macros & closures.  In many systems, this may be a practical
> > > solution, although that's subjective.
> >
> > Actually, I think closures are a terrible way to implement objects,
> > beyond the 'that's neat' level.  Lack of introspection is the first
> > thing that comes to mind...
> 
> You're saying that closures don't have a built-in introspection capability,
> but that's the point.

Err... that's not a response I expected, I'll give you that.

> If they did, they'd have a particular kind of introspection, using a
> particular mechanism, and if you wanted some other kind, you're
> usually out of luck - either because the existing mechanism makes a
> different mechanism impractical, or because the design of the
> original mechanism didn't cater for wanting to do something
> different.  Perhaps the author of the language had some subjective
> behavior-constraining mantra in mind, like how many ways to do
> something there ought to be.

For concepts here, you might have a point.  I'm not sure introspection
is one of them, though.

> If you want objects with introspection, you can build them.  There's
> certainly no problem doing that with closures.  How do you think
> introspection works in any other language?  Someone implemented it.  

And not me!  This is my main point, I think.

> But most languages don't have the power to practically implement
> such things within the language, so whoever implemented it fixed it
> for all time in the underlying implementation language, like C.

I take it you don't want to hear about Turing completeness at this
point?

I am well aware that one's 'class defining' macros can build in some
level of introspection.  But we already have CLOS, which is infinitely
better than any object system that you or I are going to dream up as a
mere adjunct to getting something useful done.

> People looking at lambda and closures from other languages tend to
> misunderstand the level at which they can operate, because the languages
> they're used to have no equivalent.  Lambda is as much a language designer's
> tool, as it is for application programmers, and that's what Paul Graham is
> referring to - because the smartest application programmers are also
> language designers.

Not necessarily very good ones, though.

> The point about closures is that they're not an enormous blob of
> arbitrarily combined and pathologically coupled functionality, as
> objects are in most systems.  They're a minimal construct, a minimal
> computational unit, an atom.  If you doubt this, you should take a
> look at the formal rules for the behavior of lambda (the closure
> constructor), and compare it to the formal rules for the construct
> of your choice (if there even are any).
> 
> Lambda and the closures they generate are as simple as computation
> gets while still being useful, which is exactly what makes them
> useful as a building block.

I don't consider minimality a virtue in and of itself (this is why I
read comp.lang.lisp and not comp.lang.scheme, I guess).

Cheers,
mwh

-- 
  This song is for anyone ... fuck it.  Shut up and listen.
                         -- Eminem, "The Way I Am"
From: Anton van Straaten
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <8aEac.6649$yN6.533@newsread2.news.atl.earthlink.net>
Michael Hudson <···@python.net> wrote:

> "Anton van Straaten" <·····@appsolutions.com> writes:
>
> > Michael Hudson <···@python.net> wrote:
> >
> > > "Anton van Straaten" <·····@appsolutions.com> writes:
> > >
> > > > An important point, and where Paul has got it right, is that it's
> > > > actually quite easy to implement OO - just about any kind you want -
> > > > with macros & closures.  In many systems, this may be a practical
> > > > solution, although that's subjective.
> > >
> > > Actually, I think closures are a terrible way to implement objects,
> > > beyond the 'that's neat' level.  Lack of introspection is the first
> > > thing that comes to mind...
> >
> > You're saying that closures don't have a built-in introspection
capability,
> > but that's the point.
>
> Err... that's not a response I expected, I'll give you that.

I think that may be because we're talking at cross-purposes.

If the question is whether plain closures provide all the functionality of
typical object systems, the answer is obviously not.  But I was responding
to a response to the quoted claim of Paul Graham's, "Because I can
*implement* oo."

Dave Robert's response to that was "You can get there with any of these
things, it's just a matter of how many keystrokes you want to type".

My response to this boiled down to being that fewer keystrokes than you
might imagine is involved.  Whether typing those keystrokes makes sense
depends on the application, and your point of view, and even your own
capabilities.  But the fact that closures are minimal, in this context, is
their whole point.

> > If they did, they'd have a particular kind of introspection, using a
> > particular mechanism, and if you wanted some other kind, you're
> > usually out of luck - either because the existing mechanism makes a
> > different mechanism impractical, or because the design of the
> > original mechanism didn't cater for wanting to do something
> > different.  Perhaps the author of the language had some subjective
> > behavior-constraining mantra in mind, like how many ways to do
> > something there ought to be.
>
> For concepts here, you might have a point.  I'm not sure introspection
> is one of them, though.

Have you ever implemented an introspective system yourself?  It's really not
difficult.

> > If you want objects with introspection, you can build them.  There's
> > certainly no problem doing that with closures.  How do you think
> > introspection works in any other language?  Someone implemented it.
>
> And not me!  This is my main point, I think.

That's fine, that's your choice, and I said in my original posting that this
was subjective.

> > But most languages don't have the power to practically implement
> > such things within the language, so whoever implemented it fixed it
> > for all time in the underlying implementation language, like C.
>
> I take it you don't want to hear about Turing completeness at this
> point?

That was exactly the point I was addressing.  Turing completeness in this
sense is raised as a bogeyman intended to imply that you'll get stuck in the
Turing tarpit writing reams of code to do something that's already built in
to some other system.  What I'm saying, from experience, is that this isn't
always the case.  Paul Graham seems to be saying something similar.

> I am well aware that one's 'class defining' macros can build in some
> level of introspection.  But we already have CLOS, which is infinitely
> better than any object system that you or I are going to dream up as a
> mere adjunct to getting something useful done.

I don't agree.  CLOS is fine as far as it goes - really, it's a sort of
application framework, a way of structuring applications.  It's not the only
way, and in many contexts, not even close to the best way.  I think part of
this discussion depends on the kinds of applications you're writing.

> > People looking at lambda and closures from other languages tend to
> > misunderstand the level at which they can operate, because the languages
> > they're used to have no equivalent.  Lambda is as much a language
designer's
> > tool, as it is for application programmers, and that's what Paul Graham
is
> > referring to - because the smartest application programmers are also
> > language designers.
>
> Not necessarily very good ones, though.

What are you basing that on?  I think the people who don't write good
languages are the ones who're writing a language without realizing that's
what they're doing.  Any application creates a model of the problem that
it's solving, and the objects in that model collectively form a kind of
language, which you use from within a host language.  There can be benefits
to restructuring this so that you're working at a higher level, which
understands your domain objects better.  You can do that with macros on top
of CLOS objects, but in many cases, if you actually analyze this, it is huge
overkill, and you can pay for that in terms of performance, complexity, even
reliability.

> > Lambda and the closures they generate are as simple as computation
> > gets while still being useful, which is exactly what makes them
> > useful as a building block.
>
> I don't consider minimality a virtue in and of itself (this is why I
> read comp.lang.lisp and not comp.lang.scheme, I guess).

It's useful if you *need* a low-level building block.  What you actually
said originally, "closures are a terrible way to implement objects", isn't
true.  What you apparently meant was "I don't want to have to implement
objects".  That's fine then - carry on using CLOS!

Anton
From: Simon Adameit
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <pan.2004.03.28.21.02.21.958556@gmx.net>
On Sun, 28 Mar 2004 20:14:07 +0000, Dave Roberts wrote:
> 
> Note that I would actually rank first-class functions and powerful macros as
> more staggering than closures as I have been learning CL. My point isn't
> that CL doesn't have staggering features or even that closures aren't one
> of them if you're coming from a world without objects. My question is
> really, what am I missing about closures, if anything?

I'm somewhat of a long time lisp newby but from what I gather every higher
order function would be almost useless without closures.
From: Simon Adameit
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <pan.2004.03.28.21.28.19.142253@gmx.net>
On Mon, 29 Mar 2004 00:02:54 +0200, Simon Adameit wrote:

> 
> I'm somewhat of a long time lisp newby but from what I gather every higher
> order function would be almost useless without closures.

Not only those but also all the nice functional argument taking functions
like map would loose much of their value when you cant pass in a closure.

But I have never programmed in Java nor do I know what those fancy things
called inner classes are, so I cant really compare the situations ;-)
From: Rahul Jain
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <87vfkomp2z.fsf@nyct.net>
Simon Adameit <·······@gmx.net> writes:

> On Mon, 29 Mar 2004 00:02:54 +0200, Simon Adameit wrote:
>
>> 
>> I'm somewhat of a long time lisp newby but from what I gather every higher
>> order function would be almost useless without closures.
>
> Not only those but also all the nice functional argument taking functions
> like map would loose much of their value when you cant pass in a closure.
>
> But I have never programmed in Java nor do I know what those fancy things
> called inner classes are, so I cant really compare the situations ;-)

The sort() function in C works fine without closures. They're only
really important if you're side-effecting the bindings. (That's why you
have to declare the function-local bindings that an inner class refers
to to be "final" in Java. It would be too much effort to truely have
closures.)

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Pascal Costanza
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <c48o4l$rkj$1@newsreader2.netcologne.de>
Rahul Jain wrote:

> The sort() function in C works fine without closures. They're only
> really important if you're side-effecting the bindings. (That's why you
> have to declare the function-local bindings that an inner class refers
> to to be "final" in Java. It would be too much effort to truely have
> closures.)

Guy Steele said in the ll1 mailing list that Sun had a complete 
implementation of inner classes that allowed referring to, and of course 
changing, any variable in the lexical environment. This required to 
automagically allocate some of those variables on the heap instead of on 
the stack. Because of this, this early design of inner classes was 
rejected and replaced by the one that's currently available in Java. The 
argument was that automatic allocation on the heap is too inefficient 
and does not comply to the notion that heap allocation only happens when 
explicitly asked for.

He also said that Sun will hopefully switch to the more general design 
in the future. He didn't say if that would be JDK 1.6, 1.7 or 2.0. ;)

Thank god that Lispers didn't need to wait for some big company to 
change their language to include lexical closures back in the 70's. 
(Imagine for a second what Lispers would do if Lisp was only able to 
refer to "final" variables in the lexical environment...)


Pascal

-- 
1st European Lisp and Scheme Workshop
June 13 - Oslo, Norway - co-located with ECOOP 2004
http://www.cs.uni-bonn.de/~costanza/lisp-ecoop/
From: Johan Kullstam
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <87vfknmhf2.fsf@sysengr.res.ray.com>
Rahul Jain <·····@nyct.net> writes:

> Simon Adameit <·······@gmx.net> writes:
> 
> > On Mon, 29 Mar 2004 00:02:54 +0200, Simon Adameit wrote:
> >
> >> 
> >> I'm somewhat of a long time lisp newby but from what I gather every higher
> >> order function would be almost useless without closures.
> >
> > Not only those but also all the nice functional argument taking functions
> > like map would loose much of their value when you cant pass in a closure.
> >
> > But I have never programmed in Java nor do I know what those fancy things
> > called inner classes are, so I cant really compare the situations ;-)
> 
> The sort() function in C works fine without closures. They're only
> really important if you're side-effecting the bindings. (That's why you
> have to declare the function-local bindings that an inner class refers
> to to be "final" in Java. It would be too much effort to truely have
> closures.)

It's not always side-effecting the bindings.

Sometimes you just want to change the number of argument by filling in
a parameter.

Say f takes a function of one double parameter.
Now you have g which takes two doubles.  You want to hold the second
fixed and pass a function of one arg.

In lisp it is trivial to say

(let ((y 3.14))
  (f (lambda (x) (g x y))))

It is rather annoying in C because now you have make yet another
function, pass the parameter y to it via some back door like a global,
note that this makes things brittle in case you want another parameter
setting at the same time, you make yet another function with a
different global &c.

-- 
Johan KULLSTAM <··········@comcast.net> sysengr
From: Dave Roberts
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <%OL9c.24651$gA5.325279@attbi_s03>
Simon Adameit wrote:

> On Mon, 29 Mar 2004 00:02:54 +0200, Simon Adameit wrote:
> 
>> 
>> I'm somewhat of a long time lisp newby but from what I gather every
>> higher order function would be almost useless without closures.
> 
> Not only those but also all the nice functional argument taking functions
> like map would loose much of their value when you cant pass in a closure.
> 
> But I have never programmed in Java nor do I know what those fancy things
> called inner classes are, so I cant really compare the situations ;-)

Java would have a very hard time dealing with the map-like examples where
you can pass in a full closure. That is truely one of the "staggering" uses
of closures. You can get some of the effect with inner classes, but it's a
distant second to what Lisp can do, and Lisp wins hands-down in terms of
syntax.

-- 
Dave Roberts
·············@re-move.droberts.com
From: Tim Bradshaw
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <fbc0f5d1.0403290343.71b95ed@posting.google.com>
Dave Roberts <·············@re-move.droberts.com> wrote in message news:<·····················@attbi_s02>...

> So the question is, am I missing something staggering about closures, or
> have I just grasped the idea so well before that I'm missing it now? Is
> there something with closures that can't be done with objects in a Java
> world, for instance? If so, what?

I think that I'm just reiterating what other people have said (and
perhaps said better), but I think the main deal with closures is that
they provide an incredibly lightweight and transparent mechanism for
things that would be far more heavyweight in some more conventional OO
languages.

As an example, I wrote a little hack which does `python-style'
iteration (which is probably in fact just some design pattern).  For
this, objects which can be iterated over can produce an iterator, and
the iteration form just asks this thing for its next element until
it's exhausted.  ITER makes an iterator, and NEXT steps it.  Iterator
objects have just one method, so they can obviously be represented as
closures where the method is `call the closure'.  In fact NEXT has a
method for functions which just calls them, and most of the methods on
ITER that I actually wrote simply return closures - there are almost
no classes defined at all.  The whole thing is extremely transparent
and easy to understand.

--tim (this thing exists at http://www.tfeb.org/lisp/toys.html#FOR)
From: Anton van Straaten
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <%oO9c.4284$yN6.1107@newsread2.news.atl.earthlink.net>
Dave Roberts wrote:
> So the question is, am I missing something staggering about closures,
> or have I just grasped the idea so well before that I'm missing it now?
> Is there something with closures that can't be done with objects in a
> Java world, for instance? If so, what?

I've included a function below which uses nothing but nested closures
(created with lambda), and the application thereof, to calculate the
factorial of an arbitrary number m, which is set to 5 for the purposes of
this example.  You should be able to cut and paste the code into any CL to
test it; to use it in Scheme, remove the 83 occurrences of "funcall":

(funcall (funcall (funcall (lambda (m) (funcall (funcall (funcall (funcall m
(lambda (x) (lambda (x) (lambda (y) y)))) (lambda (x) (lambda (y) x)))
(lambda (s) (lambda (z) (funcall s z)))) (lambda (f) (lambda (x) (funcall
(funcall m (funcall (funcall (funcall (lambda (x) (lambda (n) (funcall
(funcall (funcall (funcall n (lambda (x) (lambda (x) (lambda (y) y))))
(lambda (x) (lambda (y) x))) (lambda (s) (lambda (z) (funcall s z))))
(lambda (f1) (lambda (x1) (funcall (funcall n (funcall (funcall (funcall x
x) (funcall (funcall (funcall n (lambda (x) (lambda (z) (funcall (funcall z
(funcall (funcall (funcall x (lambda (x) (lambda (y) x))) (lambda (n)
(lambda (s) (lambda (z) (funcall s (funcall (funcall n s) z)))))) (lambda
(s) (lambda (z) (funcall s z))))) (funcall x (lambda (x) (lambda (y)
x))))))) (lambda (z) (funcall (funcall z (lambda (s) (lambda (z) z)))
(lambda (s) (lambda (z) z))))) (lambda (x) (lambda (y) y)))) f1)) x1))))))
(lambda (x) (lambda (n) (funcall (funcall (funcall (funcall n (lambda (x)
(lambda (x) (lambda (y) y)))) (lambda (x) (lambda (y) x))) (lambda (s)
(lambda (z) (funcall s z)))) (lambda (f1) (lambda (x1) (funcall (funcall n
(funcall (funcall (funcall x x) (funcall (funcall (funcall n (lambda (x)
(lambda (z) (funcall (funcall z (funcall (funcall (funcall x (lambda (x)
(lambda (y) x))) (lambda (n) (lambda (s) (lambda (z) (funcall s (funcall
(funcall n s) z)))))) (lambda (s) (lambda (z) (funcall s z))))) (funcall x
(lambda (x) (lambda (y) x))))))) (lambda (z) (funcall (funcall z (lambda (s)
(lambda (z) z))) (lambda (s) (lambda (z) z))))) (lambda (x) (lambda (y)
y)))) f1)) x1))))))) (funcall (funcall (funcall m (lambda (x) (lambda (z)
(funcall (funcall z (funcall (funcall (funcall x (lambda (x) (lambda (y)
x))) (lambda (n) (lambda (s) (lambda (z) (funcall s (funcall (funcall n s)
z)))))) (lambda (s) (lambda (z) (funcall s z))))) (funcall x (lambda (x)
(lambda (y) x))))))) (lambda (z) (funcall (funcall z (lambda (s) (lambda (z)
z))) (lambda (s) (lambda (z) z))))) (lambda (x) (lambda (y) y)))) f))
x)))))(lambda (s) (lambda (z) (funcall s (funcall s (funcall s (funcall s
(funcall s z)))))))) (lambda (x) (+ x 1))) 0)

This isn't a very practical way to calculate factorial, but it does
illustrate some things about lambda and closures:

1.  This function was derived, automatically, from an ordinary, high-level
representation of the factorial function - it would have been tedious to
write, otherwise.  How would you do such a derivation in Java, with objects?
2.  How would you express this code with objects in Java?
3.  Would the Java version be as concise?

Of course, the real question is what the implications of this are.  It may
seem impractical.  However, the point is that the ability to create, nest
and manipulate closures is very powerful - Turing-complete, in fact.
Although in theory, you can do the same sorts of things with class-based
objects, in practice, you wouldn't want to.

One point is that class-based objects are heavyweight.  Classes can be
useful, but languages also need a lighter-weight unit of abstraction.  Many
languages offer little more than ordinary functions, or methods, but these
don't allow the sort of thing being done above.  Lambda, and the closures
they generate, provide a very flexible & powerful lighter-weight unit -
something small & simple, that you can provably do anything with.

For the practical utility of closures, look at any good program written in
CL or Scheme.  The closures may not always be as obvious as above, since
they're present behind the scenes of every lexical binding construct,
conceptually if not actually.  There are many things which are tedious to do
with objects, that are quick and easy to do with closures.

> Note that I would actually rank first-class functions and powerful macros
> as more staggering than closures as I have been learning CL.

Closures are what makes first-class functions powerful - without them,
they'd be a lot like C's function pointers - very restricted.

In summary, I'd say it's almost certain you haven't really grokked closures
yet - particularly if you're comparing them to Java objects, of all the
unwieldy things in the universe.  If you're interested, you might try
reading some of the first few papers listed on this page:
http://library.readscheme.org/page1.html

Anton
From: Tayssir John Gabbour
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <866764be.0403291341.1c6b3fc1@posting.google.com>
"Anton van Straaten" <·····@appsolutions.com> wrote in message news:<···················@newsread2.news.atl.earthlink.net>...
> For the practical utility of closures, look at any good program written in
> CL or Scheme.  The closures may not always be as obvious as above, since
> they're present behind the scenes of every lexical binding construct,
> conceptually if not actually.  There are many things which are tedious to do
> with objects, that are quick and easy to do with closures.

Would you say that objects are more comparable to environment frames
of closures, rather than closures themselves?

When a variable is unavailable in an object, it may be found in an
ancestor.  When it's unavailable in an environment frame, it may be
found in an earlier frame.

In Java, they have "methods" instead of closures, which means the only
environment they can access is that of the associated object and its
ancestors.

Little globes of state, rather than frames of state.
From: mikel
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <x_0ac.30339$2_2.5512@newssvr29.news.prodigy.com>
Tayssir John Gabbour wrote:
> "Anton van Straaten" <·····@appsolutions.com> wrote in message news:<···················@newsread2.news.atl.earthlink.net>...
> 
>>For the practical utility of closures, look at any good program written in
>>CL or Scheme.  The closures may not always be as obvious as above, since
>>they're present behind the scenes of every lexical binding construct,
>>conceptually if not actually.  There are many things which are tedious to do
>>with objects, that are quick and easy to do with closures.
> 
> 
> Would you say that objects are more comparable to environment frames
> of closures, rather than closures themselves?

An environment by itself isn't enough to be an object in the usual 
sense, because in most object systems an object is a dispatcher, 
selecting code to run based on the identity or type of the object itself 
plus the message and arguments sent to it. You can do that with a 
closure by making it examine its arguments and dispatch to some 
subroutine depending on what it finds.

In some object systems (class-bassed systems) you have to say at compile 
time where to look up variables if they aren't local; in others 
(prototype-based systems) you can say at runtime where to look up 
variables, and can change the lookup chain at any time. Some (most) 
object systems select code to run by examining the object; others (CLOS 
and systems like it) select the code to run based on any number of 
arguments to a function.

Using closures you can build any of these schemes, or build all of them 
and use them together.
From: Dave Roberts
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <8IX9c.123279$1p.1727855@attbi_s54>
Anton van Straaten wrote:

[lots of FUNCALLs... ;-)]

> Of course, the real question is what the implications of this are.  It may
> seem impractical.  However, the point is that the ability to create, nest
> and manipulate closures is very powerful - Turing-complete, in fact.
> Although in theory, you can do the same sorts of things with class-based
> objects, in practice, you wouldn't want to.

Yes. That's exactly the conclusion that I'm coming to. It's the fact that
it's so lightweight that really give it the power.

> One point is that class-based objects are heavyweight.  Classes can be
> useful, but languages also need a lighter-weight unit of abstraction. 
> Many languages offer little more than ordinary functions, or methods, but
> these
> don't allow the sort of thing being done above.  Lambda, and the closures
> they generate, provide a very flexible & powerful lighter-weight unit -
> something small & simple, that you can provably do anything with.
> 
> For the practical utility of closures, look at any good program written in
> CL or Scheme.  The closures may not always be as obvious as above, since
> they're present behind the scenes of every lexical binding construct,
> conceptually if not actually.  There are many things which are tedious to
> do with objects, that are quick and easy to do with closures.

Exactly. Because they are created automatically, with a single form, you
just use them. There is not the tedium of creating a whole class and
managing its lifecycle, etc.

>> Note that I would actually rank first-class functions and powerful macros
>> as more staggering than closures as I have been learning CL.
> 
> Closures are what makes first-class functions powerful - without them,
> they'd be a lot like C's function pointers - very restricted.

Right. I'm coming to that conclusion, too. In a certain sense, I can already
pass around a function in C, using a pointer. What I can't do is create a
closure dynamically with access to private variables, etc.

> In summary, I'd say it's almost certain you haven't really grokked
> closures yet - particularly if you're comparing them to Java objects, of
> all the
> unwieldy things in the universe.  If you're interested, you might try
> reading some of the first few papers listed on this page:
> http://library.readscheme.org/page1.html

I actually have read a few papers there. It was a help before. I should
probably go back. I find that Lisp isn't so much learned as absorbed over
time. I'm getting it piece by piece.

Thanks for the note. Very helpful.

-- 
Dave Roberts
·············@re-move.droberts.com
From: André Thieme
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <c4aj2b$bj4$1@ulric.tng.de>
Dave Roberts wrote:

> I actually have read a few papers there. It was a help before. I should
> probably go back. I find that Lisp isn't so much learned as absorbed over
> time. I'm getting it piece by piece.

I just wanted to agree to that.
I am no longer in a rush to learn it. The coming semester will keep me
from learning a lot anyway. But I see no problem in it and think not
many people became Lisp experts within five months.

Every one or two weeks one of the 99 principles is ok.


Andr�
--
From: Tayssir John Gabbour
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <866764be.0403290957.3f275bef@posting.google.com>
Before I go into this, I wonder the exact same thing too.  One of
those curiously hyped things.  But I have a programmer's take on it:


Dave Roberts <·············@re-move.droberts.com> wrote in message news:<·····················@attbi_s02>...
> So the question is, am I missing something staggering about closures, or
> have I just grasped the idea so well before that I'm missing it now? Is
> there something with closures that can't be done with objects in a Java
> world, for instance? If so, what?

One possibility is that OOP systems tend to impose their own
philosophical burdens.  Here is a common pattern in Java when you want
"function objects":

- create interfaces
- create concrete implementations
- figure out where on the HD you want to store each of them, maybe
mess around with inner classes

This happens a lot when you want to make generalized code you can
customize.  Like with a general tree-search, it would be nice to
assemble things out of parts.  But what generally happens is people
say, "Screw it" and write a specific class for a DFS, another for a
BFS...  Or take perverse satisfaction in actually implementing the
general code.

So object systems can have their own dysfunctional baggage you have to
deal with when you just want closures.  Kind of like marrying someone
and finding out you have to let her psycho boyfriend from Nebraska
live with you.  Can't always separate the good things from the bad...


And often it seems implementation inheritance is the way to emulate a
closure's "free variable environment."  (Are there many languages that
support lexical object nesting well?)  There is a lot of controversy
about that kind of inheritance.
From: Kaz Kylheku
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <cf333042.0403301149.74c93255@posting.google.com>
Dave Roberts <·············@re-move.droberts.com> wrote in message news:<·····················@attbi_s02>...
> So the question is, am I missing something staggering about closures, or
> have I just grasped the idea so well before that I'm missing it now? Is
> there something with closures that can't be done with objects in a Java
> world, for instance? If so, what?

To emulate a closure with objects, you have to do a lot of gruntwork.
Define the object, make it conform to the right interface, put in all
the right slots to keep all the state you want, make sure those slots
are initialized properly and so on.

The closure just rips an object right out of your lexical environment,
and the interface conformance is achieved by its lambda list and
semantics. This is much more convenient and expressive.

Then there are issues regarding complex nesting. You can have closures
whose environments partially overlap, because they contain some free
references to variables that are not in the scopes of their sibling
closurs, and some that are in a common enclosing scope. These splits
in the environment are transparent to the programmer.  It's not easy
to do this kind of overlapping with objects in a typical OOP language.
You need to split things up into multiple objects with substructure
sharing, which isn't going to be transparent without a whole lot of
additional work.
From: Ray Dillinger
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <4069FDFA.644B48A1@sonic.net>
Kaz Kylheku wrote:

 
> Then there are issues regarding complex nesting. You can have closures
> whose environments partially overlap, because they contain some free
> references to variables that are not in the scopes of their sibling
> closurs, and some that are in a common enclosing scope. These splits
> in the environment are transparent to the programmer.  It's not easy
> to do this kind of overlapping with objects in a typical OOP language.
> You need to split things up into multiple objects with substructure
> sharing, which isn't going to be transparent without a whole lot of
> additional work.

Y'know, Lisp closures could be a good notation for explaining and 
documenting exactly what the semantics of "objects" are in various 
OO languages. 

			Bear
From: Anton van Straaten
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <6Qmac.5933$yN6.1749@newsread2.news.atl.earthlink.net>
Ray Dillinger wrote:

> Kaz Kylheku wrote:
>
>
> > Then there are issues regarding complex nesting. You can have closures
> > whose environments partially overlap, because they contain some free
> > references to variables that are not in the scopes of their sibling
> > closurs, and some that are in a common enclosing scope. These splits
> > in the environment are transparent to the programmer.  It's not easy
> > to do this kind of overlapping with objects in a typical OOP language.
> > You need to split things up into multiple objects with substructure
> > sharing, which isn't going to be transparent without a whole lot of
> > additional work.
>
> Y'know, Lisp closures could be a good notation for explaining and
> documenting exactly what the semantics of "objects" are in various
> OO languages.

And in fact, lambda notation is used for exactly that purpose.  The idea can
be extended further, to explaining and documenting the semantics of
programming languages in general.  That's what denotational semantics does:
it maps expressions in a source language to equivalent expressions in a
lambda notation.  In books on denotational semantics, you'll find the core
semantics of a variety of languages - plain imperative, OO, and functional -
expressed in this way.

This gives you a general abstraction for programming language semantics.
It's highly tractable, since lambda notation can be manipulated and
transformed with simple and provably correct algebraic transformations.
This is useful in building tools to deal with languages.

These transformations work all the way down to the machine code level, so
the technique is particularly useful for building compilers.  Kelsey &
Hudak's 1989 paper "Realistic Compilation by Program Transformation" is a
pretty accessible intro to this idea.  Appel's book "Compiling with
Continuations" is a heavier-duty successor which describes doing this for a
subset of the SML/NJ language.  Using these techniques, the real SML/NJ
compiler generates some of the fastest native code around.

If you're really smart, you'll realize that you don't really need a machine
to translate from some funky line-noise-inspired syntax with ad-hoc
semantics, into something that's tractable, highly expressive, and
consistent.  You can just write in that form directly.  Of course, writing
in lambda notation directly is a bit low-level - see the factorial example I
posted elsewhere in this thread, for example.  You need more than just
lambda: you need lambda, some datatypes, plus macros.

The rest is fluff - mere distractions from the Unbearable Staggeringness of
Closures.  Steele & Sussman's series of papers weren't called "Lambda, the
Ultimate..." for nothing.

Anton
From: John Thingstad
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <opr5qsccinxfnb1n@news.chello.no>
Why this facination with "poor mans classes".
CLOS has more power and flexibillity (as far as I can see)
The one reason I can see is that it is more efficeint.
But that is because it does less.

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
From: Don Groves
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <opr5qzduxj2i99y2@news.web-ster.com>
On Wed, 31 Mar 2004 20:56:26 +0100, John Thingstad 
<··············@chello.no> wrote:

> Why this facination with "poor mans classes".
> CLOS has more power and flexibillity (as far as I can see)
> The one reason I can see is that it is more efficeint.
> But that is because it does less.
>


Was the name CLOS chosen partly because of CLOSures?
-- 
dg
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
From: Anton van Straaten
Subject: Re: "Staggering power of closures..."
Date: 
Message-ID: <Y4Lac.6925$yN6.1345@newsread2.news.atl.earthlink.net>
"Don Groves" <(. (@ dgroves ccwebster) net))> wrote in message
·····················@news.web-ster.com...
> On Wed, 31 Mar 2004 20:56:26 +0100, John Thingstad
> <··············@chello.no> wrote:
>
> > Why this facination with "poor mans classes".
> > CLOS has more power and flexibillity (as far as I can see)
> > The one reason I can see is that it is more efficeint.
> > But that is because it does less.
> >
>
>
> Was the name CLOS chosen partly because of CLOSures?

Well, in "The Art of the Metaobject Protocol", the source for the Closette
CLOS subset which the book presents contains the following line:

  (format t "~%Closette is a Knights of the Lambda Calculus production.")

Draw your own conclusions...

Anton