Pascal Chambon writes:
One last idea I might have : what about something like
* def myfunc(a, b, c = yield []): pass*
As syntax, I'd be -0.5. But my real problem is that the whole concept seems to violate several of the "Zen" tenets. Besides those that Steven D'Aprano mentioned, I would add two more. First is "explicit is better than implicit" at the function call. True, for the leading cases of "[]" and "{}", "def foo(bar=[])" is an easy mistake for novice Python programmers to make with current semantics. And I agree that it is very natural to initialize an unspecified list or dictionary with the empty object. But those also have a convenient literal syntax that makes it clear that the object is constructed at function call time: "myfunc([])" and "myfunc({})". Since that syntax is always available even with the proposed new semantics, I feel this proposal also violates "there's one -- and preferably only one -- obvious way to do it". I understand the convenience argument, but that is frequently rejected on Python-Dev with "your editor can do that for you; if it doesn't, that's not a problem with Python, it's a problem with your editor." I also see the elegance and coherence of Tennessee's proposal to *always* dynamically evaluate, but I don't like it. Given that always evaluating dynamically is likely to have performance impact that is as surprising as the behavior of "def foo(bar=[])", I find it easy to reject that proposal on the grounds of "although practicality beats purity". I may be missing something, but it seems to me that the proponents of this change have yet to propose any concrete argument that it is more Pythonic than the current behavior of evaluating default expressions at compile time, and expressing dynamic evaluation by explicitly invoking the expression conditionally in the function's suite, or as an argument. Regarding the syntax, the recommended format for argument defaults is def myfunc(a, b, c=None): pass Using a keyword (instead of an operator) to denote dynamically evaluated defaults gives: def myfunc(a, b, c=yield []): pass which looks like a typo to me. I feel there should be a comma after "yield", or an index in the brackets. (Obviously, there can't be a comma because "[]" can't be a formal parameter, and yield is a keyword so it can't be the name of a sequence or mapping. So the syntax probably 'works' in terms of the parser. I'm describing my esthetic feeling, not a technical objection.) As for "yield" itself, I would likely be confused as to when the evaluation takes place. "Yield" strikes me as an imperative, "give me the value *now*", ie, at compile time.