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

Accumulator



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

I disagree. Python has certainly been evolving by stealing features from
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. For one thing, the mathematical meaning of
the word "function" sort of implies statelessness.

A Lisp-er might thing that the distinction is not important for the same
reason that they would see all of the extra syntax as meaningless sugar.
But for average programmers there is a big difference between a unit of
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 not
true that: "the Perl/Lisp program is conceptually simpler, ...". I would
argue you are in a minority on that issue. 

====

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

In my mind, a better OO version would separate the incrementing from the
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 there
is a convention (often ignored) that in Python you separate value
mutation from value returning. (e.g. see the "sort" method). It reduces
the liklihood of using a mutating function thinking it is
side-effect-free and vice versa. (your admonition about the difference
between an incrementer and an accumulator shows that it is easy to
confuse these)

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 an
object that can be reset, or decremented, etc. And has the other virtues
I outlined above.

I am willing to concede that if we ignore library, community, available
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 to
exaggerate even the benefits of those if they do not understand Python's
various syntactic enhancement features (operator overloading, magic
methods, etc.)

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

 Paul Prescod