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:
- 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 requesting.
- 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,