On Thu, 16 Oct 2008 12:18:49 -0700, Aaron \"Castironpi\" Brady wrote:
[snip] >> If Python re-evaluated the default value i=i at runtime, the above >> would break. > > Not with a mere extra lambda. Not so. It has nothing to do with lambda, lambda just happens to be a convenient example. Here's the code I demonstrated: >>> for i in xrange(len(callbacks)): ... callbacks[i] = lambda s, i=i: '%d %s' % (i, s) ... >>> for cb in callbacks: ... print cb('string') ... 0 string 1 string 2 string 3 string At the end of the first loop, i == 3. If the default value i=i was re- evaluated each time the function was called, then i would get the value 3 each time, which is the same behaviour you get from the version with this: callbacks[i] = lambda s: '%d %s' % (i, s) Worse, because you're now relying on i as a global, it's subject to strange and mysterious bugs if you later change i and then call the callback. > The fact that a syntax is an opportunity > to have a behavior does not imply that it should have one. The fact > that newbies ask about these semantics doesn't imply that they'd ask > about another one just as much. The fact that these semantics have > these two uses, doesn't imply that the others don't have more. Nowhere did I say that the one logically implies the other. I was asked for examples of how the current behaviour is useful, not to prove that the current behaviour logically follows from first principles. If you want to use a programming language where function default values are re- evaluated at runtime, you know where to find them. By the way, for the record I myself has found that behaviour useful on occasion. But that's easy to do with current Python: def spam(x, y=None): if y is None: # re-evaluate the default value at runtime y = get_some_other_value() return x + y So if you want that behaviour, you can get it. But if Python's semantics changed, then how would you implement today's semantics where the default is evaluated once only? I don't think you can. So Python's current semantics allows the behaviour you want, but in a slightly inconvenient form; but the re-evaluate-at-runtime semantics would prevent the behaviour I want completely. > Immutable defaults behave identically in both. Not quite. To have immutable defaults behave identically, you would need to remove at least one more feature of Python: the ability to set a default value to an arbitrary expression, not just a literal. Why do you need to do this? This toy example demonstrates the problem if you don't: yy = 3 # immutable value bound to the name yy def spam(x, y=yy-1): return x + y will have the *expression* yy-1 re-evaluated when they call the function. That means that even though 2 is immutable, you can no longer rely on the default value being 2, or even existing at all. (What if I del yy at some point, then call the function?) So now to get the behaviour you desire, you not only have to change the way Python functions are implemented (and that will have a real and significant performance cost), but you also have to change the parser to only allow literals as default values. Note that there is absolutely nothing wrong with using an expression when setting default values. But you have to prohibit it, or else introduce unexpected behaviour which will trip up not just noobs but everybody. And then you'll have noobs writing in weekly asking why they can't write "def foo(x, y=10**6)" instead of y=10000000. -- Steven -- http://mail.python.org/mailman/listinfo/python-list