< :the previous in number
^ :the list in numerical order
> :the next in number
P :the previous (in thread)
N :the next (in thread)
|<:the top of this thread
>|:the next thread
^ :the parent (reply-to)
_:the child (an article replying to this)
>:the elder article having the same parent
<:the youger article having the same parent
---:split window and show thread lists
| :split window (vertically) and show thread lists
~ :close the thread frame
.:the index
..:the index of indices
Martin Weber wrote:
> On Sun, Mar 23, 2003 at 07:11:36AM +0900, Seth Kurtzberg wrote:
>
>>On Saturday 22 March 2003 02:09 pm, Johann Hibschman wrote:
>>
>>>Seth Kurtzberg <seth / cql.com> writes:
>>>
>>>>Ruby has closures, Python does not. Not getting into the "who's better"
>>>>argument; just citing a fact.
>>>
>>>Actually, no, that's wrong. Python has had closures for a while now.
>>>
>>>
>>>>>>def make_adder(x):
>>>
>>>.... def adder(y):
>>>.... return x + y
>>>.... return adder
>>>....
>>>
>>>
>>>>>>a10 = make_adder(10)
>>>>>>a10(2)
>>
>>I'll have to check whether python has changed, but this example is not a
>>closure.
>
>
> Mind elaborating why it isn't ? In the definition of adder the value of
> x is free, and determined by the lexical environment; make_adder defines
> it. If it wasn't a closure, a10 would depend on the value of x in the
> calling environment. It obviously doesn't. If it isn't a closure, what
> else would you call it ?
>
> -Martin
>
> PS: In about every scheme book I've seen, the classic closure example
> is
>
> (define (mk-add x)
> (lambda (n)
> (+ x n)))
That example doesn't fully explain closures. In a closure, the lambda
function has access not just to the _value_ of x but to the same binding
as in the outer scope, so the inner function can modify the value in the
outer function. For example, in Ruby (or SmallTalk or Scheme) you can do
this:
make_counter = proc { |start|
proc { |inc| start += inc }
}
counter = make_counter[0]
p counter[3] # ==> 3
p counter[2] # ==> 5
But in Python, the inner function only has access to the _object_, not
to the original variable which refers to the object, and so you have to
"box" the value inside an object if you want to have shared references.
This is what you would have to do (example in Ruby. I can't make myself
write Python code on a Saturday):
make_counter_like_python = proc { |start|
box = [start]
proc { |inc| box[0] += inc }
}
counter_py = make_counter_like_python[0]
p counter_py[3] # ==> 3
p counter_py[2] # ==> 5
I think this is what is meant when people say Python does not have closures.