Chris Rebert <cvrebert@gmail.com> wrote:
Josiah Carlson wrote:
Using the features of a language to attempt to compensate for that same language's (argued) shortcomings are a valid _and encouraged_ approach. Your poo-pooing of Python conditionals, decorators, and lambdas to solve this particular problem, to me, seems like you want a *particular solution*.
No, it's just that why use several different decorators when a slight change in semantics renders them all obsolete? Why have to use a decorator/lambda/conditional and remember when to use which? I'm trying to generalize the pattern of "reevaluate/copy default values each time they're required" into new behavior for default arguments. Indeed, as I stated in another email (no idea which one, there's been too many), I wholeheartedly support adding some of those decorators to the standard library should my PEP get rejected.
The conditional works in all cases. The lambda works in all cases. The set of decorators seems to need to be tuned depending on the situation. Me, I would just use a conditional or even a plain if statement, as it is already sufficiently universal to handle every case. Discussions about 'but then I can't mask global names with local names' are going to fall on deaf ears; it's seen as poor form, and discussing what one can do using poor Python form is not topical.
I don't see a problem with the current default argument semantics. Why? Because in the case where I would want to receive a mutable parameter, like in the case below that wouldn't work with Python's standard semantics...
def append_10(lst=[]): lst.append(10) return lst
I would presumably change it to...
def append_10(lst=None): if lst is None: lst = [] lst.append(10) return lst
Or some variant thereof. Now, here's the thing; if I want a mutable argument, then None is a nonsensical value to pass, generally, as it is not mutable. So I don't buy the whole "but then None would no longer be a valid argument to pass" bull that was offered as a reason why the above isn't a reasonable translation (I can't remember who offered it).
Nowhere has it been proposed to forbid passing None as an argument.
And I never claimed as much. There was a previous post by someone (I can't remember who offered it), saying that replacing 'lst=[]' with 'lst=None' would make it so that a user couldn't signal *something special* with a 'None' argument. I was trying to get across that such reasoning doesn't make sense in this particular context.
The basic core of the proposal is to have Python compile the code such that the boilerplate is either removed entirely (if the new semantics are the default) by no longer being necessary, or dramatically shortened via the addition of a new keyword (which would indicate the new semantics). Yes, you can manually transform your code to use the idiom you mention. But why should you have to? Why not have Python do the heavy-lifting for you?
Heavy lifting? One line change and one line addition is heavy lifting? There has got to be an episode of Monty Python embedded in this thread somewhere, because I can't help laughing at your claim.
I'm also not convinced by either of the 3 pages that talk about Python "gotchas". You get bitten by it, you learn it, understand it, and move on. If they can't figure it out, I'm not sure I want them writing Python software anyways; I certainly wouldn't want them to work on any of the Python software I work on and use.
I'm not here to argue that people shouldn't be made to understand the difference between mutable and immutable values. They definitely should know the difference. I'm just advocating a language change to make certain kinds of functions less verbose.
My point is that the change results in *certain* functions being trivially less verbose. I've spent more time working around re's call semantics than I have dealing with (incorrect assumptions about Python's) default argument semantics. As I don't see a need to change re, I don't see a need to change default argument semantics. - Josiah