It's most certainly not a mistake; Python 3 would probably have fixed it, if it were. It is an (admittedly, strange) side effect of the way 'def' works.
From this example you can see two things. First, the binding of 'x' is closed over when the lambda expression is evaluated. And second, the expression that provides the default value of 'y' is evaluated every time the function is called.
There's no fundamental reason it couldn't have worked that way in Python. (I understand that changing the language so it worked that way now would likely break some code.)
You've still got that &optional argument though. I don't see a huge amount of difference from a semantic point of view between that and the Python version though (ie. if x == None: ...).
No, the lambda expression creates the function, which is returned as the value of the let block; defvar just binds the function to a name so we can use it multiple times.
if you accept the ; to separate statements, as the lambda in python is syntactically only allowed to contain one statement.
(The introduction of the variable x into the example is not important for the behavior of default arguments, however, it is important for a separate issue. I've stripped it out here.)
Surely not. The implementation already has to check that the number of provided arguments is valid. The decision of whether to evaluate the default expression can be part of that.
The code that evaluates the default expression doesn't need to be in a separate function, either, so the argument that calling that function is too expensive also doesn't hold water.
The version with the optional parameter is actually slightly faster, which completely blows a hole in the performance argument.
Look, no language is perfect -- not even Common Lisp :-) I think users are better served when design flaws in a language are acknowledged without defensiveness than when bogus justifications are offered.
You're assuming that the function-calling overhead is the same in python as in CL. I don't think that's the case, and it definitely wasn't at the start.
I don't agree that this is a design flaw. As I recall it bit me once as a beginner, and never again in over a decade of using python, and as a lisp hacker you know you don't design a language for beginners. :-)
IMO mutable default arguments should be forbidden just as mutable keys are not accepted in dictionaries. All of the examples which claim to have a use-case for mutable default values can be rewritten with more explicit (thus more pythonic) constructs.