[Python-ideas] 'Injecting' objects as function-local constants

Terry Reedy tjreedy at udel.edu
Sun Jun 19 20:26:44 CEST 2011

On 6/19/2011 2:56 AM, Nick Coghlan wrote:

> Indeed. If anyone was curious as to why I've been recently trying to
> steer the discussion back specifically towards Jan's original idea of
> replacing current (ab)uses of the default argument hack (and nothing
> more), this is pretty much it.

Along that line, I posted the following concrete suggestion a couple of 
days ago, but have seen no response:
for the purpose of the OP, named local constants (for speed or freezing 
the meaning of an expression or both), we do not need [a new namespace]. 
There is already a fourth 'namespace' for constants, a tuple 
f.__code__.co_consts, whose 'names' are indexes, just as with the locals 
array. Given

def f(a, **, b=1001, len = len): return 2001 # one possible spelling

def f(a):                                    # alternate
     constant b = 1001, len = len
     return 2001

the compiler should put 1001 and len into co.consts and convert 'b' and 
'len' into the corresponding indexes, just like it does with 'a', and 
use the LOAD_CONST bytecode just as with literal constants like 2001 in 
the body. Constant names would not go into .co_names and not increment 
.co_argcount. This would make named constants as fast and def-time 
frozen as default args without the disadvantages of being included in 
the signature and over-writable on calls.
Did this not actually go through?

> We *know* those use cases exist because there is code in the wild that
> uses them (including in the standard library). Saying "don't do that"
> isn't an adequate response as, for anyone that knows about the hack
> and how it works, the alternatives are far harder to read (in addition
> to being far more verbose and error prone to write in the first
> place).
> Extrapolating to additional functionality that is difficult or
> impossible in current Python code is sheer speculation that is likely
> to weigh down any proposal with unnecessary cruft that gets it
> rejected.
> What is needed now is one or more volunteers that are willing and able to:
> 1. Write a PEP that:
>    - distils the core discussion in this thread down into a specific
> proposal that can be brought up on python-dev

The above is a specific proposal (with two possible syntax spellings) 
and an outline of a specific implementation.

>    - explains *why* the default argument hack is undesirable in general
> (unintuitive, hard to look up, harmful to introspection, invites
> errors when calling affected functions)
>    - clearly articulates the uses of the default argument hack that the
> proposal aims to eliminate (early binding, shared locals, performance)

By 'shared locals' do you mean nonlocals? That is not quite what Jan was 

>    - include real world example of such uses from the standard library
> (and potentially other code bases)
>    - optionally, also describe the potential "function factories" that
> could be developed based on the semantics I proposed (see Eric Snow's
> post for a sketch of how such factories might work once given a
> template function to work with)
> 2. Create a reference implementation targeting Python 3.3
> (with step 1 being significantly more important at this stage - while
> the implementation can't be called *easy*, it should be a reasonably
> straightforward combination of the existing code that handles nonlocal
> statements and that which handles the calculation and storage of
> default arguments).

I do not see what nonlocals has to do or needs to have to do with 
*local* constants. My proposal is that to store named constants, we 
reuse the current code to recognize and calculate named defaulted locals 
with the current code to store and retrieve anonymous constants,

Terry Jan Reedy

More information about the Python-ideas mailing list