5 ms·
I have only a trivial amount of experience experience with Scheme, could you explain how its closures are different from Python's? I haven't used Java a lot ei
by JeremyBanks 15y ago
I have only a trivial amount of experience experience with Scheme, could you explain how its closures are different from Python's?
I haven't used Java a lot either, but from what I have done Python's function seems more similar to JavaScript than to Java.
- irahul 15y ago> I have only a trivial amount of experience experience with Scheme, could you explain how its closures are different from Python's? In pre Python 3, the closed over value isn't mutable unless it's a reference to a mutable object. def counter(num): def foo(): num += 1 return num return foo c = counter(5) c() This won't work because you can't mutate the closed variable `start`. This would work in languages with proper closures(Ruby, Perl, Scheme...). Here is how you do it in Ruby: def counter(n) lambda { n += 1 } end c = counter(5) c[] # returns 6 c.call() # Alternate syntax. returns 7 c[] # returns 8 The above python will work in Python 3 if the closed variable is declared `nonlocal`. def counter(num): def foo(): nonlocal num num += 1 return num return foo Or you can have workarounds in pre Python3. def counter(num): def foo(): foo.num += 1 return foo.num foo.num = num return foo
- kbd 15y agoI dunno if I'd say that's an issue of Python not having proper closures, or just that before you could say 'nonlocal' there was no way to refer to the outer scope, since the only scopes you could refer to were 'local' and 'global'.
- deleted 15y ago[deleted]
- irahul 15y ago> In pre Python 3, the closed over value isn't mutable unless it's a reference to a mutable object. > Proper closures were added in Python 2.2 (which is quite old at this point), not Python 3. x is a reference to a mutable object(list), and it's not x which is mutated but what x refers to. Pre python 3 doesn't have proper closures - ways to emulate it, yes. Proper closures - no.
- bobbyi 15y agoPython has had proper closures since version 2.2, which is quite old at this point. You can verify this using the following code: def func(): x = [] def func2(): x.append(1) return x return func2 closed = func(); closed(); assert closed() == [1,1] closed = func(); closed(); assert closed() == [1,1]
- spacemanaki 15y agoThat's what I was referring to as "Java closures".
- MostAwesomeDude 15y agoPython closes over names, not objects. This is consistent with the rest of Python, which treats names as references to objects rather than variables which hold objects. I do agree that it's confusing for people used to closures and used to languages with different semantics.
- peteretep 15y agoIn Perl, for reference: use strict; use warnings; sub counter { my $n = $_[0]; return sub { ++$n } } my $c = counter( 5 ); say $c->(); say $c->();
- draegtun 15y agoAnd its also handy that you can create a closure without needing to define a subroutine: my $c = do { my $n = 5; sub { ++$n } };