[Python-ideas] Explicit variable capture list

Chris Angelico rosuav at gmail.com
Tue Jan 19 19:38:45 EST 2016


On Wed, Jan 20, 2016 at 11:14 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Wed, Jan 20, 2016 at 10:29:48AM +1100, Chris Angelico wrote:
>> On Wed, Jan 20, 2016 at 3:47 AM, Guido van Rossum <guido at python.org> wrote:
>> > I think it's reasonable to divert this discussion to "value capture". Not
>> > sure if that's the usual terminology, but the idea should be that a
>> > reference to the value is captured, rather than (as Python normally does
>> > with closures) a reference to the variable (implemented as something called
>> > a "cell").
>>
>> +1. This would permit deprecation of the "def blah(...., len=len):"
>> optimization - all you need to do is set a value capture on the name
>> "len".
>
> Some might argue that the default argument trick is already the One
> Obvious Way to capture a value in a function.

I disagree. There is nothing obvious about this, outside of the fact
that it's already used in so many places. It's not even obvious after
looking at the code.

> I don't think deprecation is the right word here, you can't deprecate
> "len=len" style code because it's just a special case of the more
> general name=expr function default argument syntax. I suppose a linter
> might complain if the expression on the right hand side is precisely the
> same as the name on the left, but _len=len would trivially work around
> that.

The deprecation isn't of named arguments with defaults, but of the use
of that for no reason other than optimization. IMO function arguments
should always exist primarily so a caller can override them. In
contrast, random.randrange has a parameter _int which is not mentioned
in the docs, and which should never be provided. Why should it even be
exposed? It exists solely as an optimization.

Big one for the bike-shedding: Is this "capture as local" (the same
semantics as the default arg - if you rebind it, it changes for the
current invocation only), or "capture as static" (the same semantics
as a closure if you use the 'nonlocal' directive - if you rebind it,
it stays changed), or "capture as constant" (what people are usually
going to be doing anyway)?

ChrisA


More information about the Python-ideas mailing list