how to write function that returns function
Bengt Richter
bokr at oz.net
Thu May 16 21:01:17 EDT 2002
On 16 May 2002 23:52:47 GMT, bokr at oz.net (Bengt Richter) wrote:
>On 15 May 2002 16:04:05 -0700, spam at bugbear.com (Paul Graham) wrote:
>
>>> 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:
>>
>>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...)
>>
>>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; this is kind
>>of a hello_world of that genre. (It's not a homework problem,
>>I swear.)
>>
>>Incidentally, here is Perl 5 code someone sent me for this case:
>>
>>sub foo {
>> my ($n) = @_;
>> return sub {return $n += $_[0]}}
>>
><flame shields up>
> >>> foo = lambda y:([x for x in [[y]]], (lambda: (x.append(x.pop()+1),x[0])[1]))[1]
> >>> f=foo(20)
> >>> f()
> 21
> >>> f()
> 22
> >>> f=foo(-4)
> >>> [f() for x in 'x'*7]
> [-3, -2, -1, 0, 1, 2, 3]
></flame shields up>
>
>;-)
>
>
Since [].append returns None, we could use short cut eval rules to prog a tiny bit more clearly:
>>> foo = lambda y:[[x for x in [[y]]], lambda:x.append(x.pop()+1) or x[0]][1]
>>> f=foo(4)
>>> [f() for x in xrange(5)]
[5, 6, 7, 8, 9]
Better yet:
>>> foo = lambda y:[lambda:x.append(x.pop()+1) or x[0] for x in [[y]]][0]
>>> f=foo(4)
>>> [f() for x in '.......']
[5, 6, 7, 8, 9, 10, 11]
Regards,
Bengt Richter
More information about the Python-list
mailing list