[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Accumulator

--Paul Prescod wrote:
> Paul suggests that this will one-day be legal Python based on the
> natural tendency for Lisp features to accumulate in Python:
> > def foo(n):
> >   lambda i: n += i

(He means http://www.paulgraham.com/icad.html.  At least, I don't 
think I said this on ll1-discuss.)

> I disagree. Python has certainly been evolving by stealing features
> other languages but most recently it has been evolving in directions
> that allow one to avoid anonymous functions and closures. I think of
> Python as an OO language and I think most other people do also. That
> means that even though a function is a first-class object, it is a
> stateless first-class object. 
> A binding of state and code is called an "instance" and instances are
> created with classes. That functions can hold state will come as a
> surprise to many programmers. 

It's not the function that holds state.  The variable holds
state, and the function has a handle on it.  You can see the
difference when you consider several functions that refer
to the same variable.  Which incidentally is something you
can't do with the hack of simulating a closure using a 
method plus fields to hold the values.

> For one thing, the mathematical meaning of
> the word "function" sort of implies statelessness.

I think programming languages long ago discarded the idea
that subroutines were functions in this sense.  The mathematical
idea of a function also implies no side effects, for example.

> A Lisp-er might thing that the distinction is not important for the
> reason that they would see all of the extra syntax as meaningless
> But for average programmers there is a big difference between a unit
> code and a combination of code and data and it is worth making that
> distinction syntactically. So I think that for most programmer it is
> true that: "the Perl/Lisp program is conceptually simpler, ...". I
> argue you are in a minority on that issue. 

I mean conceptually simpler in the formal sense that the program 
has fewer elements.  (I'm only a minority in that sense if other
people can't count ;-)

> ====
> Also, I understand that you tried hard to get idiomatic Python, but I
> think that your specification of the problem was already Lisp-biased.


If it is Lisp-biased, why does Perl do so well?  Or Smalltalk?

Actually, I was surprised how badly Python did.  I had till
then believed the story that Python was equivalent to Lisp
except for macros.  I was kind of shocked, for example, to 
find that you can't put the same things in the body of a
lambda expression as you can in a named function.  That
just seems like a bug to me.

> In my mind, a better OO version would separate the incrementing from
> value-returning, for flexibility, clarity and safety. Otherwise, if I
> want the same value twice I have to store it away or add 0. Plus
> is a convention (often ignored) that in Python you separate value
> mutation from value returning. (e.g. see the "sort" method). It
> the liklihood of using a mutating function thinking it is
> side-effect-free and vice versa. (your admonition about the
> between an incrementer and an accumulator shows that it is easy to
> confuse these)

Even within the Lisp world there is debate about this.  Scheme
set! doesn't return the new value.  I personally think this is
excessively governessy.  You can always not use the returned
value if you don't want to.

> Finally, I would use a meaningful method name rather than operator
> overloading (which makes more sense in a functional rather than OO
> language).
> class acc:
>     def __init__(self, n):
>         self.cur = n
>     def inc(self, i):
>         self.cur += i
> f = acc(5)
> f.inc(2)
> f.inc(3)
> print f.cur
> f.inc(4)
> f.inc(2)
> print f.cur
> It is my opinion (just an opinion) that this would be more
> understandable to the vast majority of Java/C++/Basic and even Perl
> programmers than the Lisp idiom. It also generalizes more easily to
> object that can be reset, or decremented, etc. And has the other
> I outlined above.

A Cadillac sedan would be more understandable to the vast 
majority of American drivers than a Porsche 911.  That does
not make it a better car.

There is a role in the world (a *big* role economically) for 
mediocre stuff that is popular because people are more used
to it.  It's dangerous as a designer, though, not to distinguish
consciously in your own mind between when you are just 
trying to get the best answer and when you are pandering
to dufuses.

Also, if a language is designed for dufuses, you should
not be disappointed if it loses to other languages in
technical comparisons.  You're not trying to win there.
When you design for dufuses, you measure victory by the
number of eight inch thick flourescent pink books about
your language on the shelves at the local bookstore, not 
what people on ll1-discuss think of it.

> I am willing to concede that if we ignore library, community,
> extensions and environment, Common Lisp probably has more pure
> linguistic power than Python. But mutable closures are not the issue.
> Macros are the issue. And there is probably a tendency for a Lisper
> exaggerate even the benefits of those if they do not understand
> various syntactic enhancement features (operator overloading, magic
> methods, etc.)

Mutable closures, as you call them, are pretty useful.  If I
remember correctly, every page generated by the Viaweb editor 
used this technique.

As for macros, none of Lisp's features exists in isolation.
Macros would be not be nearly as good without rest parameters,
or lexical scope.

I don't know Python of course, but the word "various" sets
off alarm bells...

> Also, if anyone has time, I would be curious what the Common Lisp
> equivalent of the class-based version looks like.

God only knows.

Do You Yahoo!?
LAUNCH - Your Yahoo! Music Experience