[Python-ideas] Explicit variable capture list
Ryan Gonzalez
rymg19 at gmail.com
Tue Jan 19 19:33:55 EST 2016
On January 19, 2016 5:51:15 PM CST, Steven D'Aprano <steve at pearwood.info> wrote:
>On Tue, Jan 19, 2016 at 03:10:35PM +0100, haael at interia.pl wrote:
>>
>> Hi
>>
>> C++ has a nice feature of explicit variable capture list for lambdas:
>>
>> int a = 1, b = 2, c = 3;
>> auto fun = [a, b, c](int x, int y){ return a + b + c + x + y};
>
>For the benefit of those who don't speak C++, could you explain what
>that does? Are C++ name binding semantics the same as Python's?
>
No.
>Specifically, inside fun, does "a" refer to the global a? If you rebind
>global a, what happens to fun?
>
>fun(0, 0) # returns 6
>a = 0
>fun(0, 0) # returns 5 or 6?
>
The given C++ lambda syntax copies the input parameters, so it would return 5.
This would return 6:
auto fun = [&a, &b, &c](int x, int y){ return a + b + c + x + y};
>
>
>> This allows easy construction of closures. In Python to achieve that,
>you need to say:
>>
>> def make_closure(a, b, c):
>> def fun(x, y):
>> return a + b + c + x + y
>> return def
>> a = 1
>> b = 2
>> c = 3
>> fun = make_closure(a, b, c)
>
>I cannot tell whether the C++ semantics above are the same as the
>Python
>semantics here. Andrew's response to you suggests that it is not.
>
>
>
>> My proposal: create a special variable qualifier (like global and
>> nonlocal) to automatically capture variables
>
>"Variables" is an ambiguous term. I don't want to get into a debate
>about "Python doesn't have variables", but it's not clear what you mean
>
>here. Python certainly has names, and values, and when you talk about
>"variables" do you mean the name or the value or both?
>
>
>> a = 1
>> b = 2
>> c = 3
>> def fun(x, y):
>> capture a, b, c
>> return a + b + c + x + y
>>
>> This will have an effect that symbols a, b and c in the body of the
>> function have values as they had at the moment of function creation.
>> The variables a, b, c must be defined at the time of function
>> creation. If they are not, an error is thrown.
>
>If I have understood you correctly, we can already do that in
>Python, and don't even need a closure:
>
>a, b, c = 1, 2, 3
>fun = lambda x, y, a=a, b=b, c=c: a + b + c + x + y
>
>
>will capture the current *value* of GLOBAL a, b and c, store them as
>default values, and use them as the LOCAL a, b and c.
>
>You may consider it a strength or a weakness that they are exposed as
>regular function parameters:
>
>fun(x, y) # intended call signature
>fun(x, y, a, b, c) # actual call signature
>
>but if you really care about hiding the extra parameters, a second
>approach will work:
>
>from functools import partial
>a, b, c = 1, 2, 3
>fun = partial(lambda a, b, c, x, y: a + b + c + x + y, a, b, c)
>
>
>If a, b, c are mutable objects, you can make a copy of the value:
>
>fun = partial(lambda a, b, c, x, y: a + b + c + x + y,
> a, b, copy.copy(c)
> )
>
>for example.
>
>Does your proposal behave any differently from these examples?
--
Sent from my Nexus 5 with K-9 Mail. Please excuse my brevity.
More information about the Python-ideas
mailing list