Velocity Reviews > accumulators

# accumulators

Eugene Van den Bulke
Guest
Posts: n/a

 06-12-2004
Hi,

I have just finished reading Paul Graham Hackers & Painters book (which
I recommend even though he seems a bit hard on Python)

In chapter 13 of his book he wants to demonstrate LISP power VS other
languages (to be precise he wants to illustrate what he means by
relative power of programming language).

"We want to write a function that generates accumulators - a function
that takes a number n, and returns a function that takes another number
i and returns n incremented by i (that's incremented by, not plus. An
accumulator has to accumulate).

In Common Lisp this would be:
(defun foo (n)
(lambda (i) (incf n i)))

....

Python doesn't fully support lexical variables, you have to create a
data structure to hold the value of n. And although Python does have a
function data type, there is no literal representation for one (unless
the body is only a single expression) so you need to create a named
function to return. This is what you end up with:

def foo(n):
s=[n]
def bar(i):
s[0]+=i
return s[0]
return bar
"

It seems to me that this code does the job (but I am not sure I
understand exactly what an accumulator is):

def test(n):
return lambda i: n+i

Is that an accumulator? If it is, PG must have written this chapter
working on an older verion of Python ...

Regards,

Eugene Van den Bulke

Paul Rubin
Guest
Posts: n/a

 06-12-2004
Eugene Van den Bulke <(E-Mail Removed)> writes:
> It seems to me that this code does the job (but I am not sure I
> understand exactly what an accumulator is):
>
> def test(n):
> return lambda i: n+i
>
> Is that an accumulator? If it is, PG must have written this chapter
> working on an older verion of Python ...

No. The idea of an accumulator is that whenever you call it, the
internal state updates. That is, if accum(n) creates an accumulator,
you should be able to say:

a = accum(3) # create accumulator holding 3
print accum(2) # prints "5"
print accum(3) # prints "8"
print accum(1) # prints "9"

etc. The Pythonic way to do it is with a class instance:

class accum:
def __init__(self, n):
self.s = n
def __call__(self, i):
self.s += i
return self.s

a = accum(3)
(etc.)

however, for programmers comfortable with the Lisp idioms of using
internal lambdas, the class/object approach is cumbersome.

Peter Otten
Guest
Posts: n/a

 06-12-2004
Paul Rubin wrote:

> a = accum(3) # create accumulator holding 3
> print accum(2) # prints "5"
> print accum(3) # prints "8"
> print accum(1) # prints "9"

Should be

a = accum(3) # create accumulator holding 3
print a(2) # prints "5"
print a(3) # prints "8"
print a(1) # prints "9"

Peter

Paul Rubin
Guest
Posts: n/a

 06-12-2004
Peter Otten <(E-Mail Removed)> writes:
> Should be
>
> a = accum(3) # create accumulator holding 3
> print a(2) # prints "5"
> print a(3) # prints "8"
> print a(1) # prints "9"

Oops, yes.

Eugene Van den Bulke
Guest
Posts: n/a

 06-12-2004
Paul Rubin wrote:
> Peter Otten <(E-Mail Removed)> writes:
>
>>Should be
>>
>> a = accum(3) # create accumulator holding 3
>> print a(2) # prints "5"
>> print a(3) # prints "8"
>> print a(1) # prints "9"

>
>
> Oops, yes.

thank you !!!

Leif K-Brooks
Guest
Posts: n/a

 06-13-2004
Paul Rubin wrote:
> class accum:
> def __init__(self, n):
> self.s = n
> def __call__(self, i):
> self.s += i
> return self.s

Just for fun, a full-blown class with documentation and the like:

class Accumulator(object):
"""This class implements a simple accumulator. Instate it with a
starting value, or it will default to 0. It can be called with
another value, which will be accumulated. The current value will
also be returned.

Example:

>>> a = Accumulator(1)
>>> a(2)

3
>>> a(1)

4
>>> a(3)

7
"""

__slots__ = '_value'

def __init__(self, value=0):
self._value = value

def __call__(self, value):
self._value += value
return self._value

def __str__(self):
return str(self._value)

def __repr__(self):
return "<Accumulator object with value %s>" % self._value

Michele Simionato
Guest
Posts: n/a

 06-13-2004
Leif K-Brooks <(E-Mail Removed)> wrote in message news:<j3Nyc.3335\$(E-Mail Removed)>. ..
> Just for fun, a full-blown class with documentation and the like:
>
> class Accumulator(object):
> """This class implements a simple accumulator. Instate it with a
> starting value, or it will default to 0. It can be called with
> another value, which will be accumulated. The current value will
> also be returned.
>
> Example:
>
> >>> a = Accumulator(1)
> >>> a(2)

> 3
> >>> a(1)

> 4
> >>> a(3)

> 7
> """
>
> __slots__ = '_value'
>
> def __init__(self, value=0):
> self._value = value
>
> def __call__(self, value):
> self._value += value
> return self._value
>
> def __str__(self):
> return str(self._value)
>
> def __repr__(self):
> return "<Accumulator object with value %s>" % self._value

I just don't see the need to use __slots__ here. The first rule about __slots__
is: don't use them! OTOH the second rule (for expert only) is: don't use them!!

That's true for any optimization, isnt'it?

Michele Simionato

Scott David Daniels
Guest
Posts: n/a

 06-25-2004
Paul Rubin wrote:

> ... The Pythonic way to do it is with a class instance:
>
> class accum:
> def __init__(self, n):
> self.s = n
> def __call__(self, i):
> self.s += i
> return self.s
>
> a = accum(3)
> (etc.)
>
> however, for programmers comfortable with the Lisp idioms of using
> internal lambdas, the class/object approach is cumbersome.

The way I'd do it is:

class accum:
def __init__(self, start):
self.runningtotal = start

def increment(self, value):
self.runningtotal += value
return self.runningtotal

a = accum(3).increment
Then you can use:
a(3) ...

That is, avoid magic names unless needed, and make the names obvious.

--
-Scott David Daniels
http://www.velocityreviews.com/forums/(E-Mail Removed)

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is OffTrackbacks are On Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post ballpointpenthief C Programming 10 09-21-2006 01:26 AM Jyothirmai Computer Security 0 11-09-2005 03:41 AM