On Fri, Sep 07, 2018 at 10:39:07AM +1200, Greg Ewing wrote: > As for whether consistent naming is a good idea, seems to > me it's the obvious thing to do when e.g. you're overriding > a method, to keep the signature the same for people who want > to pass arguments by keyword. You'd need to have a pretty > strong reason *not* to keep the parameter names the same. > > Given that, it's natural to want a way to avoid repeating > yourself so much when passing them on. > > So I think the underlying idea has merit, but the particular > syntax proposed is not the best.
But the proposal isn't just for a way to avoid repeating oneself when overriding methods: class Parent: def spam(self, spam, eggs, cheese): ... class Child(Parent): def spam(self, foo, bar, baz): # why the change in names? ... I agree that inconsistency here is a strange thing to do, and its a minor annoyance to have to manually repeat the names each time you override a class. Especially during rapid development, when the method signatures haven't yet reached a stable API. (But I don't know of any alternative which isn't worse, given that code is read far more often than its written and we don't design our language to only be usable for people using IntelliSense.) The proposal is for syntax to make one specific pattern shorter and more concise when *calling arbitrary functions*. Nothing to do with inheritance at all, except as a special case. It is pure syntactic sugar for one specific case, "name=name" when calling a function. Syntactic sugar is great, in moderation. I think this is too much sugar for not enough benefit. But I acknowledge that's because little of my code uses that name=name idiom. (Most of my functions take no more than three arguments, I rarely need to use keywords, but when I do, they hardly ever end up looking like name=name. A quick and dirty manual search of my code suggests this would be useful to me in less than 1% of function calls.) But for those who use that idiom a lot, this may seem more appealing. With the usual disclaimer that I understand it will never be manditory to use this syntax, nevertheless I can see it leading to the "foolish consistency" quote from PEP 8. "We have syntax to write shorter code, shorter code is better, so if we want to be Pythonic we must design our functions to use the same names for local variables as the functions we call." -- hypothetical blog post, Stackoverflow answer, opinionated tutorial, etc. I don't think this is a pattern we want to encourage. We have a confluence of a few code smells, each of which in isolation are not *necessarily* bad but often represent poor code: - complex function signatures; - function calls needing lots of arguments; - needing to use keyword arguments (as otherwise the function call is too hard to read); - a one-to-one correspondence between local variables and arguments; and syntax designed to make this case easier to use, and hence discourage people from refactoring to remove the pain. (If they can.) I stress that none of these are necessarily poor code, but they are frequently seen in poor code. As a simplified example: def function(alpha, beta, gamma): ... # later, perhaps another module def do_something_useful(spam, eggs, cheese): result = function(alpha=eggs, beta=spam, gamma=cheese) ... In this case, the proposed syntax cannot be applied, but the argument from consistency would suggest that I ought change the signature of do_something_useful to this so I can use the syntax: # consistency is good, m'kay? def do_something_useful(beta, alpha, gamma): result = function(*, alpha, beta, gamma) ... Alternatively, I could keep the existing signature: def do_something_useful(spam, eggs, cheese): alpha, beta, gamma = eggs, spam, cheese result = function(*, alpha, beta, gamma) ... To save seventeen characters on one line, the function call, we add an extra line and thirty-nine characters. We haven't really ended up with more concise code. In practice, I think the number of cases where people *actually can* take advantage of this feature by renaming their own local variables or function parameters will be pretty small. (Aside from inheritance.) But given the "consistency is good" meme, I reckon people would be always looking for opportunities to use it, and sad when they can't. (I know that *I* would, if I believed that consistency was a virtue for its own sake. I think that DRY is a virtue, and I'm sad when I have to repeat myself.) We know from other proposals [don't mention assignment expressions...] that syntax changes can be accepted even when they have limited applicability and can be misused. It comes down to a value judgement as to whether the pros are sufficiently pro and the cons insufficiently con. I don't think they do: Pros: - makes one specific, and (probably unusual) pain-point slightly less painful; - rewards consistency in naming when consistency in naming is justified. Cons: - creates yet another special meaning for * symbol; - implicit name binding instead of explicit; - discourages useful refactoring; - potentially encourages a bogus idea that consistency is a virtue for its own sake, regardless of whether it makes the code better or not; - similarly, it rewards consistency in naming even when consistency in naming is not needed or justified; - it's another thing for people to learn, more documentation needed, extra complexity in the parser, etc; - it may simply *shift* complexity, being even more verbose than the status quo under some circumstances. -- Steve _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/