On Mon, May 18, 2020 at 11:32:29AM -0700, Caleb Donovick wrote:
Certainly the way default arguments work with mutable types is not the most intuitive
Neither is the alternative. def function(arg=calculate_default_value()): "What do you mean that extremely expensive calculation is performed on every function call?" "What do you mean, my default value can change from one call to the next, if the ennvironment changes?" Besides, there are at least two distinct semantics of late-binding for default values, and I guarantee that which ever one we pick, somebody is going to complain that it's the wrong one and "not intuitive". - late-bound defaults are closures, like nested functions; - late-bound defaults aren't closures, but like global lookups. Trying to base programming semantics on "intuition" is a losing prospect, because people's intuition depends so critically on their level of knowledge. To me, it is intuitively obvious that of course function defaults use early binding. Function definitions are executable statements, which implies that the default is evaluated at the same time the `def` is executed, not when the function is called. If you can't have a choice between early and late binding in a language, the sensible choice is to use early binding: - early binding is easier to implement and more efficient; - given early binding at the language level, providing late binding semantics in the function is trivial; - but given late binding at the language level, providing early binding semantics in the function is horrible. So if you asked me, I would say that early binding is the obvious, intuitive choice for function defaults. I've worked with people who insist that early binding is the "intuitive" choice in one context, and then insist that early binding is totally confusing and late binding is the "intuitive" choice in another context. And they don't like having their own words quoted back at them *wink* -- Steven