how to write function that returns function
Michael Hudson
mwh at python.net
Thu May 16 05:07:06 EDT 2002
spam at bugbear.com (Paul Graham) writes:
> > You can't directly translate that. Access to variable of enclosing
> > scopes is read only (except in the case of global statements, but that
> > doesn't help here).
>
> It looks as if the closest thing would be something like this,
> which a Python expert sent me:
Well yeah, that's what I meant by "can't directly translate"...
> def foo(n):
> s = [n]
> def bar(i):
> s[0] += i
> return s[0]
> return bar
>
> Although you can't modify variables from outer scopes, you can
> modify *parts* of them (which to me seems like the same thing...)
Really? I think there's quite a difference.
> The reason this problem seems kind of artificial is that I don't
> need to solve this actual problem. I heard that recent Python
> versions had added more support for lexical closures, and was
> curious how well Python works for the type of programming in
> Structure and Interpretation of Computer Programs;
Ah, the real question! The answer: not well.
> this is kind of a hello_world of that genre
Well, I just swiped this from the online version of SICP:
(define (make-withdraw balance)
(lambda (amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds")))
(define W1 (make-withdraw 100))
(define W2 (make-withdraw 100))
(W1 50)
50
(W2 70)
30
(W2 40)
"Insufficient funds"
(W1 40)
10
I don't suppose you need telling that in Python you do this like so:
class Balance:
def __init__(self, balance):
self.balance = balance
def withdraw(self, amount):
if amount <= self.balance:
self.balance -= amount
return self.balance
else:
return "Insufficient funds"
>>> W1 = Balance(100)
>>> W2 = Balance(100)
>>> W1.withdraw(50)
50
>>> W2.withdraw(70)
30
>>> W2.withdraw(40)
'Insufficient funds'
>>> W1.withdraw(40)
10
? (Ignoring the fact that Python has exceptions...)
> (It's not a homework problem, I swear.)
I didn't think someone called Paul Graham who signs himself pg was
still doing homework...
> Incidentally, here is Perl 5 code someone sent me for this case:
>
> sub foo {
> my ($n) = @_;
> return sub {return $n += $_[0]}}
Yuck <wink>.
Cheers,
M.
--
This makes it possible to pass complex object hierarchies to
a C coder who thinks computer science has made no worthwhile
advancements since the invention of the pointer.
-- Gordon McMillan, 30 Jul 1998
More information about the Python-list
mailing list