[Python-3000] pre-PEP: Default Argument Expressions

Chris Rebert cvrebert at gmail.com
Thu Feb 15 02:35:04 CET 2007


Mike Klaas wrote:
> On 2/13/07, Chris Rebert <cvrebert at gmail.com> wrote:
>>      This PEP proposes new semantics for default arguments to remove
>>      boilerplate code associated with non-constant default argument 
>> values,
>>      allowing them to be expressed more clearly and succinctly.
>> Specifically,
>>      all default argument expressions are re-evaluated at each call as
>> opposed
>>      to just once at definition-time as they are now.
> 
> Seems like a huge barrel of worms.  The binding semantics are not only
> a problem for mutable arguments, as you state in your pep:
> 
> In [2]: def a():
>   ...:     g = 1
>   ...:     def b():
>   ...:         print g
>   ...:     g = 2
>   ...:     return b
>   ...:
> In [4]: a()()
> 2
> 
> In [5]: def a():
>   ...:     g = 1
>   ...:     def b(g=g):
>   ...:         print g
>   ...:     g = 2
>   ...:     return b
> In [6]: a()()
> 1
> 
> Creating closures and define-time local bindings is certainly not as
> common as a "regular" function definition, it is important part of
> python when programming in a semi-functional style.  Imagine that "def
> b" is in a for loop.  Your presented alternatives either don't work or
> go to rather extreme effort to duplicate this simple and useful
> functionality.

The refactorings mentioned in the PEP were specifically for mutable
arguments. I didn't consider the case you mentioned. The first snippet
you give would be unaffected by the PEP's changes. As for the second case:

while whatever:
     #code
     g = 1
     def b(g=g):
         print g
     g = 2
     b() #=> 1
     #code

It could be modified like so:

while whatever:
     #code
     g = 1
     retro_g = g
     def b(g=retro_g):
         print g
     g = 2
     b() #=> 1
     #code

> I agree that newbies stumble over mutable default arguments.  I did.
> If we could improve that learning process, I would be all for it.
> However, besides this being a significant change in semantics, two
> main stumbling blocks in my mind are:
> 
> 1. Scoping.  Scoping issues are not minor consequences of changes to
> default argument behavior, but are integral.  I think that you'd have
> to come up with a more obvious way to accomplish all the various
> current behaviors of def args before changing their semantics.  This
> is probably a larger project than the original proposal.

Well, as the PEP mentions, new syntax could be added to access the old
semantics, or alternatively, to enable the new semantics, though I'd
prefer to avoid adding syntax. However, finding refactorings for various
uses of the current semantics is very relevant to the PEP. I'll be sure
to add you case and any others mentioned to the PEP.

> 2. Performance.  The speed of python is influenced greatly by the
> performance of function dispatch.  This may not show up in pystone.

Clarification: as Anthony Baxter mentioned, I used pybench, not pystone. 
However, if someone recommends a better benchmark to measure the
performance impact of the proposed change, I'd be all for it.

- Chris Rebert



More information about the Python-3000 mailing list