Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Depends on the language. "Closure" (at least to me) doesn't imply this bevaior in a language with mutable variables. And then you have pure languages and languages which only support mutation through reference values, in which his explanation would be correct.


> "Closure" (at least to me) doesn't imply this bevaior in a language with mutable variables.

I don't think I can name a single reasonably-known language with mutable variables and closures that doesn't exhibit this behavior.


Indeed. Python is a prime example of a language with closures that doesn't do variable-name binding, due to the way variables and specifically assignments work in general with Python.


I'm sorry? Python is the same way:

    >>> i = 10
    >>> def x():
    ...   print i
    ... 
    >>> x()
    10
    >>> i = 11
    >>> x()
    11
The value is not closed over in any language I can think of off the top of my head. It's a reference to a variable in lexical scope.

What python does slightly differently is writing to variables in outer scopes. But it still closes over references.


The writing to variables in outer scopes is what I meant by a lack of actual name-binding, due to the way Python does assignments; it seems I expressed that poorly. Here's a better attempt. The top poster's example simply doesn't work in Python:

    >>> i = 0
    >>> def inc():
    ...   i += 1
    ...
    >>> print i
    0
    >>> inc()
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 2, in inc
    UnboundLocalError: local variable 'i' referenced before assignment
So variables are name-bound in the sense that you can read from their original name and reference but you can't assign in normal ways. (Python has closures, which I said, just not typical closures that other languages might have.) Leading to the pattern of wrapping an array or dict or class around the thing you're interested in.

    >>> i_wrapped = [0]
    >>> def inc():
    ...   i_wrapped[0] += 1
    ... 
    >>> print i_wrapped[0]
    0
    >>> inc()
    >>> print i_wrapped[0]
    1
One could argue that one shouldn't really have such mutable state inside a closure of the enclosed items, which I do, but a person expecting to (set!) or the like is going to be surprised.

Edit: I guess it should be said that Python 3 has the 'nonlocal' keyword, and Python 2 has the 'global' keyword for global cases, which allows for expected behavior. So the functionality is still there, but still needs an extra statement.

    >>> i = 0
    >>> def out():
    ...   i = 0
    ...   def inc():
    ...     nonlocal i
    ...     i += 1
    ...   print(i)
    ...   inc()
    ...   print(i)
    ... 
    >>> print(i)
    0
    >>> out()
    0
    1
    >>> print(i)
    0


Python is a bad example here, as its scoping rules are inconsistent and frequently surprising.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: