
On 9/27/2011 9:26 PM, Ethan Furman wrote:
Terry Reedy wrote:
On 9/27/2011 6:32 PM, Guido van Rossum wrote:
On Tue, Sep 27, 2011 at 3:24 PM, Arnaud Delobelle<arnodel@gmail.com> wrote:
I may be unduly worrying about this, but it feels to me that it lessens the overall tidiness of the language. I would much rather there was a way to initialise these "own" variables outside the body of the function.
Yes, you have a point. Hiding side effects this way could be nasty, and this is actually the first point in favor of the default argument hack I've heard in a while. :-)
I have several times written on python-list that Python has a simple rule: header expressions (for default args) are evaluated one-time when the function is defined; body expressions are evaluated (perhaps) each time when the function is called. If people understand this and do not fight it, they are not surprised that mutating a once-defined default arg mutates it, nor that defining a function inside a loop magically causes define-time binding of names in the body.
I would hate for Python to lose this simplicity. I consider it one of its positive features.
Simplicity is good.
I don't remember who first suggested it, and I don't remember any discussion on it, but what if decorator functions grew a __prepare__ method similar to metaclasses?
At least three people, including Guido, have noted than a keyword-only _private parameter solves most of the problems with using default args for constants. Since the _underscore convention is already partly built into the language (import *, help(module), __mangling, __reserved__), we can have other tools like signature introspection also respect the convention. This solution *also* works for the semi-private accumulator parameter of most tail-recursive functions. Example: sum the values in a linked list (without iterators or explicit loops*: def llsum(ll, *, _total = 0): if ll: return llsum(ll[1], _total = _total + ll[0]) else: return _total The private parameter _total is constant for outside calls but gets a new value with each recursive call. It should not appear in the public signature but is used internally. The non-parameter constants proposed as a substitute for default args would not work for this case. * I am QUITE aware that this can be rewritten with while, and indeed I write the two if branches in the order I do to make it easy. def llsum(ll) total = 0): while ll: ll, total = ll[1], total + ll[0] else: return total But this is a different issue. -- Terry Jan Reedy