From: Tj
Subject: Closures vs. objects
Date: 
Message-ID: <ccc7084.0303042203.f057f86@posting.google.com>
Lexical closures are often mentioned as an important advantage. 
However, languages which don't have them often use things like objects
for these tasks.  I understand closures are very elegant and I
personally like them, but am I missing something in thinking that this
is a somewhat flimsy issue?  For example, it seems that the Java
designers made the conscious design choice to make functions weaker
and have objects take on much of the load.

Maybe my sense is that other issues are more important.  Like, map is
overwhelmingly painful in some languages.  OTOH, perhaps the closure
example is something that many languages are deficient in, making it a
better choice.  Python's solution is both disturbing and yet
interesting.

Basically I'm wondering if this is more of a rhetoric issue, or one
whose significance I don't yet understand as someone new to lisp.

Thanks,
 Tj

From: Rob Warnock
Subject: Re: Closures vs. objects
Date: 
Message-ID: <18OcncT0S79OXPijXTWc-g@speakeasy.net>
Tj <··········@yahoo.com> wrote:
+---------------
| Lexical closures are often mentioned as an important advantage. 
| However, languages which don't have them often use things like objects
| for these tasks.  I understand closures are very elegant and I
| personally like them, but am I missing something in thinking that
| this is a somewhat flimsy issue?
+---------------

Yes, I think so. While not strictly "necessary", they allow you to
*significantly* extend the protocols of higher-order functions without
requiring any changes to them, nor any knowledge of your extensions.

+---------------
| Maybe my sense is that other issues are more important. Like, map is
| overwhelmingly painful in some languages.
+---------------

Well consider this: In Lisp you can pass a *closure* to map, too!
Or to any other higher-order function.

As a completely trivial example, consider using that ability to instrument
your particular Lisp implementation's built-in SORT function to see how
often and in what order it compares things while it's sorting, even though
there are no such hooks defined as part of SORT's calling sequence:

	> (let ((seq (copy-seq '(8 3 1 9 2 0 4 6 5 7)))
		(trace '())
		(count 0))
	    (flet ((my-less-than (x y)        ; closure over TRACE & COUNT
		     (push (cons x y) trace)
		     (incf count)
		     (< x y)))
	      (setq seq (sort seq #'my-less-than))
	      (values seq (nreverse trace) count)))
	=>
	(0 1 2 3 4 5 6 7 8 9)
	((3 . 8) (9 . 1) (0 . 2) (6 . 4) (7 . 5) (1 . 3)
	 (9 . 3) (9 . 8) (4 . 0) (4 . 2) (0 . 1) (2 . 1)
	 (2 . 3) (4 . 3) (4 . 8) (6 . 8) (5 . 0) (5 . 1)
	 (5 . 2) (5 . 3) (5 . 4) (5 . 6) (7 . 6) (7 . 8))
	24
	> 

So SORT first compared 3 & 8, then it compared 9 & 1, then 0 & 2, etc.,
making a total of 24 comparisons in all. Interesting.

In C, you can fake closures, but *only* by designing the protocol for
*all* of your higher-order functions to accept -- for each function
pointer you might pass it as an argument -- *both* a function pointer
and an "opaque data cookie" [i.e., a place to hide the closure data],
the latter of which *must* be passed to the corresponding function
whenever it's called (in addition to the other parameters it requires).

But the last time I looked at the man pages for libc's qsort(3),
heapsort(3), & mergesort(3), the comparison function argument was
only defined to have two parameters, e.g.:

	void qsort(void *base, size_t nmemb, size_t size,
                   int (*compar)(const void *, const void *));

Common Lisp SORT also only knows about the two required parameters for
the binary comparison predicate (*not* anything about any additional
cookie to pass it), yet even so we were able to access the lexical
environment of the calling code, without changing the interface protocol.


-Rob

p.s. Another problem with faking closures in C is that the "closure
data" often has to be allocated with "malloc()" before the call to
the higher-order function, and then deallocated after the call returns.
Sometimes. Depending of the function being passed in this particular case
(and the closure data being passed in this particular case). But if you
get it wrong... Can you say "memory leak"? Or maybe "double-free panic"?

Or consider how much simpler GUI (and other) "callbacks" become if you
always pass them fully-general closures rather "with a cookie here, no
cookie there, sometimes a cookie, sometimes no cookie... Old X Windows
had a crash, eee-aii-eeee-aaiii-OOHHHHH!"

-----
Rob Warnock, PP-ASEL-IA		<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Gareth McCaughan
Subject: Re: Closures vs. objects
Date: 
Message-ID: <slrnb6be78.293r.Gareth.McCaughan@g.local>
T J Scarlet wrote:
> Lexical closures are often mentioned as an important advantage. 
> However, languages which don't have them often use things like objects
> for these tasks.  I understand closures are very elegant and I
> personally like them, but am I missing something in thinking that this
> is a somewhat flimsy issue?  For example, it seems that the Java
> designers made the conscious design choice to make functions weaker
> and have objects take on much of the load.

Whatever you can do with closures you can do with objects.
For that matter, whatever you can do with objects you can
do in C, and whatever you can do in C you can do with a
Turing machine. (As far as the expressive power of the
*language* goes.)

However, compare the following two examples. Since the
point is to compare syntactic overhead, I've put them
both in the same language, which is Python with a slightly
altered "sort" function :-). The version with classes
would be uglier, both relatively and absolutely, in
Java or C++.

    def sorted_by_closeness(points, base_point):
      return sort(points,
                  key = lambda p: distance(p,base_point))

    def sorted_by_closeness(points, base_point):
      class DistanceCalculator:
        def __init__(self, p):
          self.base = p
        def __call__(self, point):
          return distance(point, self.base)
      return sort(points, key = DistanceCalculator(base_point))

And yes, I know that what Perl programmers call "the
Schwartzian transform" and some other people call
"decorate/sort/undecorate" is likely to be better
here; it's just an example.

It also just happens that in Python you get lexical
scoping to some extent for locally defined classes,
so the example above could have been written

    def sorted_by_closeness(points, base_point):
      class DistanceCalculator:
        def __call__(self, point):
          return distance(point, base_point)
      return sort(points, key = DistanceCalculator(base_point))

I don't think that's true in most languages that make you
use classes instead of closures. (Note that Python doesn't;
the first example above is legal Python.)

Another issue that isn't shown by these examples: what if
you want your (pseudo-)closure to be able to alter variables
in the calling scope? You can't do that with closures in
Python because closed-over variables are immutable. You
can't do it more "directly" with classes either because
with that approach you need to make copies of all the
variables you're pretending to close over. I think Java
has the same problem, but I'm prepared to be corrected.
I'm certain C++ has. So that's another set of hoops to
jump through when you don't have closures: extracting the
results from the pseudo-closure when you're done with it.

All perfectly possible, if you don't want the affected code
becoming three times as long. That's all.

-- 
Gareth McCaughan  ················@pobox.com
.sig under construc
From: Marco Antoniotti
Subject: Re: Closures vs. objects
Date: 
Message-ID: <v7q9a.21$qc.740@typhoon.nyu.edu>
You *do* realyze that you posted on C.L.L., *don't* you?

Are you ready for the flames coming your way? :) (With attached 
statements about the manifest inferiority of Python, of course) :)

Cheers


Marco Antoniotti




Gareth McCaughan wrote:

> T J Scarlet wrote:
>
> >Lexical closures are often mentioned as an important advantage.
> >However, languages which don't have them often use things like objects
> >for these tasks.  I understand closures are very elegant and I
> >personally like them, but am I missing something in thinking that this
> >is a somewhat flimsy issue?  For example, it seems that the Java
> >designers made the conscious design choice to make functions weaker
> >and have objects take on much of the load.
>
>
> Whatever you can do with closures you can do with objects.
> For that matter, whatever you can do with objects you can
> do in C, and whatever you can do in C you can do with a
> Turing machine. (As far as the expressive power of the
> *language* goes.)
>
> However, compare the following two examples. Since the
> point is to compare syntactic overhead, I've put them
> both in the same language, which is Python with a slightly
> altered "sort" function :-). The version with classes
> would be uglier, both relatively and absolutely, in
> Java or C++.
>
>     def sorted_by_closeness(points, base_point):
>       return sort(points,
>                   key = lambda p: distance(p,base_point))
>
>     def sorted_by_closeness(points, base_point):
>       class DistanceCalculator:
>         def __init__(self, p):
>           self.base = p
>         def __call__(self, point):
>           return distance(point, self.base)
>       return sort(points, key = DistanceCalculator(base_point))
>
> And yes, I know that what Perl programmers call "the
> Schwartzian transform" and some other people call
> "decorate/sort/undecorate" is likely to be better
> here; it's just an example.
>
> It also just happens that in Python you get lexical
> scoping to some extent for locally defined classes,
> so the example above could have been written
>
>     def sorted_by_closeness(points, base_point):
>       class DistanceCalculator:
>         def __call__(self, point):
>           return distance(point, base_point)
>       return sort(points, key = DistanceCalculator(base_point))
>
> I don't think that's true in most languages that make you
> use classes instead of closures. (Note that Python doesn't;
> the first example above is legal Python.)
>
> Another issue that isn't shown by these examples: what if
> you want your (pseudo-)closure to be able to alter variables
> in the calling scope? You can't do that with closures in
> Python because closed-over variables are immutable. You
> can't do it more "directly" with classes either because
> with that approach you need to make copies of all the
> variables you're pretending to close over. I think Java
> has the same problem, but I'm prepared to be corrected.
> I'm certain C++ has. So that's another set of hoops to
> jump through when you don't have closures: extracting the
> results from the pseudo-closure when you're done with it.
>
> All perfectly possible, if you don't want the affected code
> becoming three times as long. That's all.
>
From: Florian Weimer
Subject: Re: Closures vs. objects
Date: 
Message-ID: <87y93tsew3.fsf@deneb.enyo.de>
Marco Antoniotti <·······@cs.nyu.edu> writes:

> Are you ready for the flames coming your way? :) (With attached
> statements about the manifest inferiority of Python, of course) :)

Python is more and more becoming Common Lisp without macros. 8-)
From: Marco Antoniotti
Subject: Re: Closures vs. objects
Date: 
Message-ID: <Klu9a.27$qc.885@typhoon.nyu.edu>
Do you mean that the Python folks are going to adopt Sexprs as syntax?

Now,  THAT would be an application of Greenspun's Tenth. :)

Cheers




Florian Weimer wrote:

> Marco Antoniotti  writes:
>
>
> >Are you ready for the flames coming your way? :) (With attached
> >statements about the manifest inferiority of Python, of course) :)
>
>
> Python is more and more becoming Common Lisp without macros. 8-)
From: Florian Weimer
Subject: Re: Closures vs. objects
Date: 
Message-ID: <8765qv7yl0.fsf@deneb.enyo.de>
Marco Antoniotti <·······@cs.nyu.edu> writes:

> Do you mean that the Python folks are going to adopt Sexprs as
> syntax?

If you decide not support macros, you can get a way with a less
uniform syntax. 8-)
From: Florian Weimer
Subject: Re: Closures vs. objects
Date: 
Message-ID: <873clz7ykp.fsf@deneb.enyo.de>
Marco Antoniotti <·······@cs.nyu.edu> writes:

> Do you mean that the Python folks are going to adopt Sexprs as
> syntax?

If you decide not support macros, you can get away with a less uniform
syntax. 8-)
From: Bruce Hoult
Subject: Re: Closures vs. objects
Date: 
Message-ID: <bruce-F6A68D.10221408032003@copper.ipg.tsnz.net>
In article <··············@deneb.enyo.de>,
 Florian Weimer <··@deneb.enyo.de> wrote:

> Marco Antoniotti <·······@cs.nyu.edu> writes:
> 
> > Do you mean that the Python folks are going to adopt Sexprs as
> > syntax?
> 
> If you decide not support macros, you can get away with a less uniform
> syntax. 8-)

If you want to support macros then you should have a relatively uniform 
syntax, but it doesn't have to be as stark as Sexprs.

Dylan allows three different syntaxes for macro calls (one is the same 
as function application, one is usually used for defining control 
structures, one is used to define new types of declarations), plus there 
are special operators used in macro definitions to match infix 
expressions, statement blocks, and a couple of other things that would 
be tedious to match yourself.  Not as simple as CL, but nowhere near the 
baroque mess you'd need to do proper macros for C++.

-- Bruce
From: Gareth McCaughan
Subject: Re: Closures vs. objects
Date: 
Message-ID: <slrnb6e7nq.7su.Gareth.McCaughan@g.local>
Marco Antoniotti wrote:

[after I used Python syntax as a "neutral" way of expressing
a comparison between closures and objects]
> You *do* realyze that you posted on C.L.L., *don't* you?
> 
> Are you ready for the flames coming your way? :) (With attached 
> statements about the manifest inferiority of Python, of course) :)

I've very seldom been flamed either for posting Python on c.l.l
or for posting Lisp on c.l.py. :-) And I *was* careful to mention
at least one deficiency in Python; I wouldn't want to be thought
a turncoat...

-- 
Gareth McCaughan  ················@pobox.com
.sig under construc
From: Kalle Olavi Niemitalo
Subject: Re: Closures vs. objects
Date: 
Message-ID: <877kbcpwk5.fsf@Astalo.kon.iki.fi>
Gareth McCaughan <················@pobox.com> writes:

>     def sorted_by_closeness(points, base_point):
>       class DistanceCalculator:
>         def __call__(self, point):
>           return distance(point, base_point)
>       return sort(points, key = DistanceCalculator(base_point))

I don't know Python.  If class DistanceCalculator closes over the
base_point parameter of sorted_by_closeness, then why must
base_point be given again when instantiating the class?
From: Michael Hudson
Subject: Re: Closures vs. objects
Date: 
Message-ID: <7h3fzq0h2fg.fsf@pc150.maths.bris.ac.uk>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> Gareth McCaughan <················@pobox.com> writes:
> 
> >     def sorted_by_closeness(points, base_point):
> >       class DistanceCalculator:
> >         def __call__(self, point):
> >           return distance(point, base_point)
> >       return sort(points, key = DistanceCalculator(base_point))
> 
> I don't know Python.  If class DistanceCalculator closes over the
> base_point parameter of sorted_by_closeness, then why must
> base_point be given again when instantiating the class?

Because he forgot to edit his example properly.

At least, I presume that's the answer.

Cheers,
M.

-- 
  The only problem with Microsoft is they just have no taste.
              -- Steve Jobs, (From _Triumph of the Nerds_ PBS special)
                         and quoted by Aahz Maruch on comp.lang.python
From: Marco Antoniotti
Subject: Re: Closures vs. objects
Date: 
Message-ID: <q7N9a.54$qc.1353@typhoon.nyu.edu>
Michael Hudson wrote:

> Kalle Olavi Niemitalo  writes:
>
>
> >Gareth McCaughan  writes:
> >
> >
> >>    def sorted_by_closeness(points, base_point):
> >>      class DistanceCalculator:
> >>        def __call__(self, point):
> >>          return distance(point, base_point)
> >>      return sort(points, key = DistanceCalculator(base_point))
> >
> >I don't know Python.  If class DistanceCalculator closes over the
> >base_point parameter of sorted_by_closeness, then why must
> >base_point be given again when instantiating the class?
>
>
> Because he forgot to edit his example properly.


You mean some random extra spaces got where they were not supposed to be? :)


Cheers

--
Marco

>
From: Gareth McCaughan
Subject: Re: Closures vs. objects
Date: 
Message-ID: <slrnb6fq7a.7su.Gareth.McCaughan@g.local>
Kalle Olavi Niemitalo wrote:

> >     def sorted_by_closeness(points, base_point):
> >       class DistanceCalculator:
> >         def __call__(self, point):
> >           return distance(point, base_point)
> >       return sort(points, key = DistanceCalculator(base_point))
> 
> I don't know Python.  If class DistanceCalculator closes over the
> base_point parameter of sorted_by_closeness, then why must
> base_point be given again when instantiating the class?

An error on my part. Sorry. Please imagine that the last
occurrence of "base_point" in the example isn't there.

-- 
Gareth McCaughan  ················@pobox.com
.sig under construc
From: Kaz Kylheku
Subject: Re: Closures vs. objects
Date: 
Message-ID: <cf333042.0303051023.40020935@posting.google.com>
··········@yahoo.com (Tj) wrote in message news:<··························@posting.google.com>...
> Lexical closures are often mentioned as an important advantage. 
> However, languages which don't have them often use things like objects
> for these tasks.

You have just invoked the ``tasks subset'' fallacy. It goes like this:
For some subset of all programming tasks, it's possible to choose
between two language features A and B, which can be applied with equal
ease. Therefore it's necessary to just have one of them, not both.
What's wrong with this argument?

> I understand closures are very elegant and I
> personally like them, but am I missing something in thinking that this
> is a somewhat flimsy issue?

Rationalization of the fallacy: The argument is slightly wrong because
there are tasks outside of the subset which were ignored. But, without
citing any supporting evidence, we can assert that they are not
important, and the only reason A or B might be preferred for them is
some religious issue, or aesthetic taste. There isn't actually any
technical reason.

> For example, it seems that the Java
> designers made the conscious design choice to make functions weaker
> and have objects take on much of the load.

To make conscious design choices, you have to be conscious.

> Basically I'm wondering if this is more of a rhetoric issue, or one
> whose significance I don't yet understand as someone new to lisp.

The second.

> Thanks,

You're welcome.
From: Tj
Subject: Re: Closures vs. objects
Date: 
Message-ID: <ccc7084.0303051519.294bfb41@posting.google.com>
···@ashi.footprints.net (Kaz Kylheku) wrote in message news:<····························@posting.google.com>...
> > For example, it seems that the Java
> > designers made the conscious design choice to make functions weaker
> > and have objects take on much of the load.
> 
> To make conscious design choices, you have to be conscious.

Isn't Guy Steele the chairman of a Lisp standards committee, and also
a coauthor of the Java language specification?  Some ad hominem
attacks are well-considered, but I'm not sure about this one.  The
original Java whitepaper made it clear that its design goals were
aimed at the "average" programmer who just wanted little culture shock
and a big "relevant" library.  (Yes, that came across as sarcastic to
me too.)


> You have just invoked the ``tasks subset'' fallacy. It goes like this:
> For some subset of all programming tasks, it's possible to choose
> between two language features A and B, which can be applied with equal
> ease. Therefore it's necessary to just have one of them, not both.
> What's wrong with this argument?

Well, a good design deals with reducing feature creep.  For example, I
might want add-squares in the language.  The question is seeing where
the line of triviality lies.  And the context of the design goals --
in certain contexts an implementation might simply provide
add-squares.  So, simply labelling something an X fallacy doesn't
reduce our job of thinking design through.

HOWEVER, everyone's patient, great replies made me realize that
looking at one feature in isolation is a mistake.  With enough
orthogonality, the right features can play off each other and gain
enormous value.  Maybe I should check Paul Graham's site and see if
this was emphasized enough in what he wrote; if not, I can email him
about this.  (Of course, he might have noticed that power scares
people off, so maybe I should leave the poor guy alone.)  This
specific example was also in the preface of his _Ansi Common Lisp_.

Thanks to everyone,
  Tj
From: Vlad S.
Subject: Re: Closures vs. objects
Date: 
Message-ID: <87of4onmdd.fsf@shawnews.cg.shawcable.net>
··········@yahoo.com (Tj) writes:

> ···@ashi.footprints.net (Kaz Kylheku) wrote in message news:<····························@posting.google.com>...
> > > For example, it seems that the Java
> > > designers made the conscious design choice to make functions weaker
> > > and have objects take on much of the load.
> > 
> > To make conscious design choices, you have to be conscious.
> 
> Isn't Guy Steele the chairman of a Lisp standards committee, and also
> a coauthor of the Java language specification?  Some ad hominem
> attacks are well-considered, but I'm not sure about this one.  The
> original Java whitepaper made it clear that its design goals were
> aimed at the "average" programmer who just wanted little culture shock
> and a big "relevant" library.  (Yes, that came across as sarcastic to
> me too.)

Not to troll, but I think some key people behind Java deserve that. I
really couldn't believe my eyes when I first read some of the things
James Gosling said in a particular interview*. What I find even more
annoying is that my current provider of higher education (which just
happens to be Gosling's alma mater, and I've decided will be mine as
well soon, sans degree) of course finds it necessary to flaunt one of
the few distinguished alumni and readily shoves the crap about "I
[Gosling] was kind of the guy responsible for the original Emacs, 23
years ago" into press releases and such (at least the CS department
had the decency to credit him as the creator of the "Unix Emacs
editor"). For some reason, I also think it is more than a coincidence
that most of the CS machines are Suns and the cirriculum has been
changed from C++ to Java recently (I will concede that this may
actually be choosing the lesser evil, but it's all relative).

If you take all the MS-bashing quotes from that interview* and
replaces references to Java with Smalltalk, you have probably the most
accurate and, in my opinion, kind description of Java that one can
make. Too bad I don't find using ugly, crippled languages as amusing
as Gosling does (I wonder how much of his "own dog food" he eats - at
least MS coders can make that claim).

* - http://news.com.com/2008-1082-817522.html

Vlad
From: Tj
Subject: Re: Closures vs. objects
Date: 
Message-ID: <ccc7084.0303070725.6ae3068@posting.google.com>
Vlad S. <··········@hotmail.com> wrote in message news:<··············@shawnews.cg.shawcable.net>...
> Not to troll, but I think some key people behind Java deserve that. I
> really couldn't believe my eyes when I first read some of the things
> James Gosling said in a particular interview*. 

If you want to talk nontechnical, I tend to filter out most of what
Sun says in official statements and interviews.  Gosling in
particular.  So obviously untrustworthy.  Their message is that they
are always right, that problems can be papered over; in a recent
interview a Sun marketing guy was talking blue sky about how Sun had
all the angles and will win every possible scenario.  The pale-face,
he full of shit.  Even Microsoft marketing doesn't sound like that.

But I was responding to someone who was talking about Java and Python
from a design standpoint.

Tj
From: Alan Baljeu
Subject: Re: Closures vs. objects
Date: 
Message-ID: <6gcaa.9259$Or5.1082146@news20.bellglobal.com>
> If you ...
> replaces references to Java with Smalltalk, you have probably the most
> ... , in my opinion, kind description of Java that one can
> make.
I hope I didn't err in the editing.  The most kind description of Java
possible is to talk about smalltalk instead.  Is this what you meant to say?
:-0
From: Vlad S.
Subject: Re: Closures vs. objects
Date: 
Message-ID: <87wuj9vkqh.fsf@shawnews.cg.shawcable.net>
"Alan Baljeu" <·······@sympatico.deleteme.ca> writes:

> > If you ...
> > replaces references to Java with Smalltalk, you have probably the most
> > ... , in my opinion, kind description of Java that one can
> > make.
> I hope I didn't err in the editing.  The most kind description of Java
> possible is to talk about smalltalk instead.  Is this what you meant to say?
> :-0

Maybe I should have been less ambiguous about the context of that
statement. Specifically it applies to these two quotes from the
aforementioned interview:

"But the other answer is, 'You guys still don't get it,' because it's
sort of Java with reliability, productivity and security deleted."

"So on the one hand, they copied Java, and on the other hand, they
added gratuitous things and other things that are outright
stupid. That's amusing."

From my (albeit somewhat limited) knowledge of Smalltalk-80, Squeak
and the historical design goals of Smalltalk at PARC, it really does
look like Java is a poor imitation, and I think that those statements
when applied to it describe Java's shortcomings pretty well.

Vlad
From: Kaz Kylheku
Subject: Re: Closures vs. objects
Date: 
Message-ID: <cf333042.0303071034.587f6b3c@posting.google.com>
··········@yahoo.com (Tj) wrote in message news:<···························@posting.google.com>...
> ···@ashi.footprints.net (Kaz Kylheku) wrote in message news:<····························@posting.google.com>...
> > > For example, it seems that the Java
> > > designers made the conscious design choice to make functions weaker
> > > and have objects take on much of the load.
> > 
> > To make conscious design choices, you have to be conscious.
> 
> Isn't Guy Steele the chairman of a Lisp standards committee, and also
> a coauthor of the Java language specification?  Some ad hominem
> attacks are well-considered, but I'm not sure about this one.  The
> original Java whitepaper made it clear that its design goals were
> aimed at the "average" programmer who just wanted little culture shock
> and a big "relevant" library.  (Yes, that came across as sarcastic to
> me too.)

I think that if you design a crap of a programming language, and you
still want a well-written specification that hangs together, Steele is
your man. As a bonus, you have a celebrity card to pull in
anticipation of derogatory remarks from the Lisp community.

There is nothing in the design of Java itself that smells like
Steele-quality work. I have no idea how much he actually had to do
with the language.

Steele co-wrote _C: A Reference Manual_ with Samuel Harbison. This is
a very good book, second only to the ANSI standard itself as a
must-have for C programmers.

Should we hold the C language above criticism because a Lisper
co-wrote the best reference manual?
From: Pascal Costanza
Subject: Re: Closures vs. objects
Date: 
Message-ID: <b4aq6e$4h4$1@f1node01.rhrz.uni-bonn.de>
Kaz Kylheku wrote:

> I think that if you design a crap of a programming language, and you
> still want a well-written specification that hangs together, Steele is
> your man. As a bonus, you have a celebrity card to pull in
> anticipation of derogatory remarks from the Lisp community.
> 
> There is nothing in the design of Java itself that smells like
> Steele-quality work. I have no idea how much he actually had to do
> with the language.

At a panel discussion Guy Steele had the following to say:

"I had a chance to help write the specification for the Java programming 
language. [...] I was brought in not [to do] a designer's job but [to 
do] a biographer's job. My principle contribution to the language was 
that as I was writing [the] specificaton [...] I would constantly return 
to James Gosling and say: I could describe what you did in twenty pages, 
or you could make a simple change and I could describe it in two pages, 
which do you want?"

The panel discussion can be downloaded as a Quicktime movie at 
http://www.ai.mit.edu/projects/dynlangs/wizards-panels.html - Paul 
Graham also participated, and in case you have doubts, this is 
definitely related to Lisp. ;)


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Bob Bane
Subject: Re: Closures vs. objects
Date: 
Message-ID: <3E6CE69D.1010706@removeme.gst.com>
Kaz Kylheku wrote:

 > ··········@yahoo.com (Tj) wrote in message
 > news:<···························@posting.google.com>...
 >
 > There is nothing in the design of Java itself that smells like
 > Steele-quality work. I have no idea how much he actually had to
 > do with the language.
 >

I just dug up some notes I took at a JavaOne conference in 1996.  At 
that conference, John Gage (chief science officer at Sun) told the crowd 
there was a point in Java's evolution where Bill Joy had recently 
discovered it, and wanted Gosling to make major changes in the language. 
  He gave no details, but apparently the two of them were seriously at 
odds with each other.  According to him, a compromise design was 
brokered between them by Guy Steele.

I've never heard this anywhere else since, but it sounds plausible, 
given Steele's role in Common Lisp's development.
From: Tim Bradshaw
Subject: Re: Closures vs. objects
Date: 
Message-ID: <ey3wujew1c2.fsf@cley.com>
* Tj  wrote:

> Basically I'm wondering if this is more of a rhetoric issue, or one
> whose significance I don't yet understand as someone new to lisp.

I think the advantage of closures is lightness - no need to spend
hours defining some use-once thing - and transparency - no need to
spend hours working out just what the closure should contain, it will
just automatically contain all the lexically apparent bindings
(including things like block names, for downward closures).

Of course you can do all this with objects, but you have to do more
work, and for something that is used once this makes code
significantly larger and harder to read.

--tim
From: Matthias Heiler
Subject: Re: Closures vs. objects
Date: 
Message-ID: <b44ga8$78t$1@trumpet.uni-mannheim.de>
Hi,

In a sense lexical closures and objects are the same thing.  I think Sussman 
and Steele discovered that when playing with Scheme in the 70s.  In these 
days objects were called "actors".  I don't have the definite reference 
handy, though.

 Matthias

Tj wrote:

> Lexical closures are often mentioned as an important advantage.
> However, languages which don't have them often use things like objects
> for these tasks.  I understand closures are very elegant and I
> personally like them, but am I missing something in thinking that this
> is a somewhat flimsy issue?  For example, it seems that the Java
> designers made the conscious design choice to make functions weaker
> and have objects take on much of the load.
> 
> Maybe my sense is that other issues are more important.  Like, map is
> overwhelmingly painful in some languages.  OTOH, perhaps the closure
> example is something that many languages are deficient in, making it a
> better choice.  Python's solution is both disturbing and yet
> interesting.
> 
> Basically I'm wondering if this is more of a rhetoric issue, or one
> whose significance I don't yet understand as someone new to lisp.
> 
> Thanks,
>  Tj
From: Kaz Kylheku
Subject: Re: Closures vs. objects
Date: 
Message-ID: <cf333042.0303051116.6d07f36d@posting.google.com>
Matthias Heiler <······@nospam.de> wrote in message news:<············@trumpet.uni-mannheim.de>...
> Hi,
> 
> In a sense lexical closures and objects are the same thing.

In the same sense that a PostScript file written by hand, and a
PostScript file generated from a high-level markup language are the
same thing!

You can feed both of them to a PostScript printer to get the behavior
of printing.

But one had to be painstakingly detailed by a human being, whereas the
other was automatically produced from semantic information extracted
from a higher level specification.

Programmers of dumb languages can't see this, because they think that
when they are defining a class and instantiating it, they are doing
object-oriented programming, which is the most high-level, abstract,
best-of-breed technology on the planet. Solving any problem is just a
matter of finding the right configuration of plumbing to hook together
instances of the right classes. If it can't be drawn using UML, it's
not a valid solution, just a hack, which is waiting to be transformed
into something ``real'' that *can* be drawn in UML. They find support
for this belief in large numbers of like-minded people, and even
entire organizations dedicated to preaching and mentoring others in
object-oriented design. The object mantra is that objects are the only
known way of decomposing software into manageable chunks which scales
to conquering the complexity of implementing large systems.

Moreover, what is understood to be object-oriented programming is the
use of a crippled object system in which a call results in at most one
method being called, chosen based on the type of one parameter only,
in which an object must belong to the same class over its entire
lifetime, in which multiple inheritance is unavailable or its use is
awkward and hence discouraged, treating methods as first-class object
and indirecting upon them is impossible, etc.
From: Steven E. Harris
Subject: Re: Closures vs. objects
Date: 
Message-ID: <87adg8l7ic.fsf@harris.sdo.us.ray.com>
···@ashi.footprints.net (Kaz Kylheku) writes:

> Programmers of dumb languages can't see this, because they think
> that when they are defining a class and instantiating it, they are
> doing object-oriented programming, which is the most high-level,
> abstract, best-of-breed technology on the planet.

[...]

Beautiful. Another message worth saving. Thanks, Kaz.

-- 
Steven E. Harris        :: ········@raytheon.com
Raytheon                :: http://www.raytheon.com
From: Joe Marshall
Subject: Re: Closures vs. objects
Date: 
Message-ID: <k7fd251z.fsf@ccs.neu.edu>
··········@yahoo.com (Tj) writes:

> Lexical closures are often mentioned as an important advantage. 
> However, languages which don't have them often use things like objects
> for these tasks.  I understand closures are very elegant and I
> personally like them, but am I missing something in thinking that this
> is a somewhat flimsy issue?  For example, it seems that the Java
> designers made the conscious design choice to make functions weaker
> and have objects take on much of the load.

Objects are a poor man's closures.  --- attributed to Norman Adams
From: Kenny Tilton
Subject: Re: Closures vs. objects
Date: 
Message-ID: <3E66217C.10506@nyc.rr.com>
FWIW, I once re-implemented Cells using closures. Thought it would 
scream. Great fun, but structs were faster. And the code was more 
readable. CLOS was slower and too big a hammer.

fwiw.

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Nicolas Neuss
Subject: Re: Closures vs. objects
Date: 
Message-ID: <87bs0pkc9n.fsf@ortler.iwr.uni-heidelberg.de>
Joe Marshall <···@ccs.neu.edu> writes:

> ··········@yahoo.com (Tj) writes:
> 
> > Lexical closures are often mentioned as an important advantage. 
> > However, languages which don't have them often use things like objects
> > for these tasks.  I understand closures are very elegant and I
> > personally like them, but am I missing something in thinking that this
> > is a somewhat flimsy issue?  For example, it seems that the Java
> > designers made the conscious design choice to make functions weaker
> > and have objects take on much of the load.
> 
> Objects are a poor man's closures.  --- attributed to Norman Adams

And the inverse (closures are the poor man's OO) is true if situations
become more difficult.  (For example, one can easily implement some
object-orientedness via closures.  But having done that one rapidly
realizes how important it is to have something more solid in hands,
e.g. for listing slots, etc..).

Fortunately, CL has both closures and CLOS:-)

Nicolas.
From: Kaz Kylheku
Subject: Re: Closures vs. objects
Date: 
Message-ID: <cf333042.0303051044.24fd2050@posting.google.com>
··········@yahoo.com (Tj) wrote in message news:<··························@posting.google.com>... 
> Basically I'm wondering if this is more of a rhetoric issue, or one
> whose significance I don't yet understand as someone new to lisp.

Here is an issue whose significance you don't understand. Some uses of
closures can in fact be replaced by the use of object. However, doing
so requires a human being who will manually transform the code so that
local variables are moved into a class, and the references are
adjusted accordingly, an instance is explicitly constructed, and so
forth.

A Python- or Java-spewing moron cannot see beyond this transformation,
because he understands programming to be a manual process performed by
a human being whose job is to emit the right incantations that tell
the machine what to do. Having to write a few extra lines manually
does not seem to him or her to be a significant reason to use a
different programming language.

But in Lisp programming, one important tool is teaching the machine
itself how to write code. This is most often done using macros. Macros
define new language features, and those language features often have
to interact with blocks of code supplied by the macro user (who might
be a human programmer, or another layer of machine programming).

A Lisp macro can, behind the scenes, place a body of code into a
closure, and then pass that closure as an object to some remote part
of the program. This is a very important type of action-at-a-distance;
distant logic interacts with and controls a local part of the program.

Without closures, this would be impossible to achieve. In some easy
cases, the encapsulation of the distant logic could be broken, and
inserted into the macro expansion. Even when achievable, this would
lead to horrible code bloat, and macros which cannot be subject any
maintenance without having to recompile everything which uses them.

So you can think of closures as virtual code-and-environment motion
through the program which is extremely useful as an implementation
substrate underneath macros for creating sophisticated new language
features. This is impossible to achieve with objects, because the
automatic environment closing is essential to the task. To do it with
an object, a macro would have to have access to the surrounding
lexical environment, and transform its local variables into a
custom-generated class. But doh, that would be a closure!

So you see, there is a big, big difference between being able to just
treat a lexical environment as an object, and having to define and
instantiate your own class.
From: Jacek Generowicz
Subject: Closures: code and environment motion
Date: 
Message-ID: <tyf4r6gwy2w.fsf_-_@pcepsft001.cern.ch>
···@ashi.footprints.net (Kaz Kylheku) writes:

> A Lisp macro can, behind the scenes, place a body of code into a
> closure, and then pass that closure as an object to some remote part
> of the program. This is a very important type of action-at-a-distance;
> distant logic interacts with and controls a local part of the program.

> So you can think of closures as virtual code-and-environment motion
> through the program which is extremely useful as an implementation
> substrate underneath macros for creating sophisticated new language
> features.

Could you give some examples of how/where you use such techniques ?
From: Kaz Kylheku
Subject: Re: Closures: code and environment motion
Date: 
Message-ID: <cf333042.0303061154.4c77bbb0@posting.google.com>
Jacek Generowicz <················@cern.ch> wrote in message news:<··················@pcepsft001.cern.ch>...
> ···@ashi.footprints.net (Kaz Kylheku) writes:
> 
> > A Lisp macro can, behind the scenes, place a body of code into a
> > closure, and then pass that closure as an object to some remote part
> > of the program. This is a very important type of action-at-a-distance;
> > distant logic interacts with and controls a local part of the program.
>  
> > So you can think of closures as virtual code-and-environment motion
> > through the program which is extremely useful as an implementation
> > substrate underneath macros for creating sophisticated new language
> > features.
> 
> Could you give some examples of how/where you use such techniques ?

Sure, for instance look at the SUPER-RESTART-CASE macro; I recently
posted a URL pointing to this. In this macro, I want the user to be
able to write restart clauses like this:

  (super-restart-case
    (some-expression ...)
    (foo () :report "The foo restart"
      a b c 
     (unwind x y z)))

If a condition handler decides to invoke (via INVOKE-RESTART) the
restart identified by symbol FOO, then control will end up evaluating
the forms A B and C. This evaluation takes place in the dynamic
context of the INVOKE-RESTART call; it's possible to use (RETURN) to
return control there. But the forms evaluated in the (UNWIND ...) are
in a ``point of no return'' zone; they are no longer in the dynamic
context of the INVOKE-RESTART call, but in an unwound context. So for
instance if (some-expression ...) were this:

   (unwind-protect
      (cause-some-condition ...)
      (print "unwinding"))

Then on invoking the FOO restart, A B C would be evaluated before the
PRINT, then "unwinding" would be printed, and then X Y Z evaluated.
The value of the Z form then becomes the result of the overall
SUPER-RESTART-CASE. Of course, you can have multiple occurences of the
UNWIND form in the body.

I tried to implement some code motion tricks in order to transform the
(UNWIND ...) pieces to a different part of the generated body of code.
This turned out to be hard to do, but closures rescued the idea.

What happens is that the (UNWIND ...) forms are packaged into a
closure, and this closure is smuggled across the non-local control
transfer that performs the unwinding. Conceptually, it looks like
this:

   (let (#:hidden-closure-0025)
     (tagbody
        ...

           ;; code in the dynamic context of the INVOKE-RESTART
           (setf #:hidden-closure-0025 #'(lambda () x y z))
           (go #:out-0026) 

        ...
      #:out-0026
      (when #:hidden-closure-0025
         (funcall #:hidden-closure-0025)))

Note that this is a first-class closure use; the closure is travelling
upward, out of the environment in which it was created, which
terminates. See, instead of moving the X Y Z code out to the tagbody
so we can GO to it, the lambda essentially lets us keep the code where
it is, and we can call back into it through the hidden variable. So
it's as if the code moved, but it didn't have to.

But this closure solution is actually better than simple code motion,
because of the environment part. If only the code X Y Z were moved
somewhere, it would fail to capture the apparently surrounding
bindings, so that code like (let ((f 42)) (unwind ... f ...)) would
not work, which would annoy users.

Also note that SETF and GO above are themselves in a closure: the body
of a RESTART-BIND handler.
From: Greg Menke
Subject: Re: Closures vs. objects
Date: 
Message-ID: <m365qxlj0i.fsf@europa.pienet>
··········@yahoo.com (Tj) writes:

> Lexical closures are often mentioned as an important advantage. 
> However, languages which don't have them often use things like objects
> for these tasks.  I understand closures are very elegant and I
> personally like them, but am I missing something in thinking that this
> is a somewhat flimsy issue?  For example, it seems that the Java
> designers made the conscious design choice to make functions weaker
> and have objects take on much of the load.
> 
> Basically I'm wondering if this is more of a rhetoric issue, or one
> whose significance I don't yet understand as someone new to lisp.


For me, they didn't seem to justify all the fuss either- until I
started using them.  If you spend some time working with closures
until you get the hang of them, I think you'll quickly find how nice
they are and how difficult other languages make the same thing.
They're certainly not a universal tool, but they do make a wide
variety of problems much easier to address.  I like closures because
they're so implicit- no extra objects, no protocols, no fiddling- a Do
What I Mean instead of a Do What I Say kind of thing.

Gregm
From: Marc Battyani
Subject: Re: Closures vs. objects
Date: 
Message-ID: <6F095F5894958098.06C6FA8E276B9220.DB76052FA6D012E3@lp.airnews.net>
"Tj" <··········@yahoo.com> wrote
> Lexical closures are often mentioned as an important advantage.
> However, languages which don't have them often use things like objects
> for these tasks.  I understand closures are very elegant and I
> personally like them, but am I missing something in thinking that this
> is a somewhat flimsy issue?  For example, it seems that the Java
> designers made the conscious design choice to make functions weaker
> and have objects take on much of the load.
>
> Maybe my sense is that other issues are more important.  Like, map is
> overwhelmingly painful in some languages.  OTOH, perhaps the closure
> example is something that many languages are deficient in, making it a
> better choice.  Python's solution is both disturbing and yet
> interesting.

Others have already explained why closures are great. I just want to
emphasis the fact that they are pervasive in c.l.l. If you need an example,
you can look at the cl-pdf sources. The main file, pdf.lisp, has less than
400 lines of code with 3 very small closures. Sure, I could have avoided
them but it's much much more convenient that way. And I knowing that I can
substitute a closure to any dictionnary value makes it very powerful.

Marc
From: Daniel Yokomiso
Subject: Re: Closures vs. objects
Date: 
Message-ID: <a1ae5139.0303081711.15568483@posting.google.com>
··········@yahoo.com (Tj) wrote in message news:<··························@posting.google.com>...
> Lexical closures are often mentioned as an important advantage. 
> However, languages which don't have them often use things like objects
> for these tasks.  I understand closures are very elegant and I
> personally like them, but am I missing something in thinking that this
> is a somewhat flimsy issue?  For example, it seems that the Java
> designers made the conscious design choice to make functions weaker
> and have objects take on much of the load.
> 
> Maybe my sense is that other issues are more important.  Like, map is
> overwhelmingly painful in some languages.  OTOH, perhaps the closure
> example is something that many languages are deficient in, making it a
> better choice.  Python's solution is both disturbing and yet
> interesting.
> 
> Basically I'm wondering if this is more of a rhetoric issue, or one
> whose significance I don't yet understand as someone new to lisp.
> 
> Thanks,
>  Tj

Hi,

    Luca Cardelli gave a talk aboutusing objects for everything. He
uses an formal object calculus (sigma calculus IIRC) and an existing
language (Obliq):

http://research.microsoft.com/Users/luca/Slides/EverythingIsAnObject.pdf


    Regarding the other posts there's a great difference between using
Java's anonymous classes vs. something like blocks in Smalltak or
Self. Statically typed languages without type-inference are always
more verbose than dynamically typed ones. Using a theoretical OO
language with type inference and object literals (Beta-like) we could
write a very terse map:


numbers.map({call self n -> n + 2})


    The brackets define an object of type Function(T,U) (defined as
the type of the map parameter) with a method named call.

    Best regards,
    Daniel Yokomiso.

"Advice is what we ask for when we already know the answer but wish we
didn't."
 - Erica Jong