On Fri, 15 May 2009 12:37:19 pm CTO wrote:
Some people don't like writing:
def f(x=SENTINEL): if x is SENTINEL: x = []
and wish to have syntax so they can write something approaching:
def f(x=[]): ...
And I understand that. However, I don't think it's important enough to make it worth changing the language, adding to Python's already significant function call overhead, or making the job of parsing function signatures more difficult. If there is a mechanism to do this inside of Python- and there are several- it is my personal opinion that those should be used in preference to modifying the language. As I am neither the smartest nor most competent programmer here, feel free to disregard my opinion- but the code I have produced matches one of the proposed syntaxes very closely, even if it is not the one you prefer.
Your code also "add[s] to Python's already significant function call overhead" as well as "making the job of parsing function signatures more difficult". I don't mean to dump on your code. What you are trying to do is obviously very difficult from pure Python code, and the solutions you have come up with are neat kludges. But a kludge is still a kludge, no matter how neat it is :) [...]
(For the record, I've suggested creating a unary-& operator so that we can write "def f(&x=[])" to get late-binding of x.)
It's simple, short, and concise. If I were to get behind a proposal to change the language to support this feature, I would probably either get behind this one or perhaps a more general system for adding a metaclass equivalent to functions. However, as things stand I remain unconvinced that any of these things are necessary, or even particularly desirable, given the aforementioned complexity of function signatures.
I think we two at least agree. I don't think there's anything wrong with the current sentinel idiom. It's not entirely intuitive to newbies, or those who don't fully understand Python's object-binding model, but I don't consider that a flaw. So I don't see the compile-time binding of default args to be a problem that needs solving. But other people do, and they are loud and consistent in their complaints. Given that the squeaky wheel (sometimes) gets the grease, I'd just like to see a nice solution to a (non-)problem rather than an ugly solution. So I'm +0 on my proposal -- I don't think it solves a problem that needs solving, but other people do. I'm -1 on decorator+lambda solutions, because not only do they not solve a problem that needs solving, but they don't solve it in a particularly ugly and inefficient way *wink*
My suggestion is neither to find another idiom or to build in late-binding support. Some people- yourself included-
I think you've misunderstood my position. I'm one of the people defending the current semantics of default arg binding. But since others want optional late binding, I'm just trying to find a syntax that doesn't bite :)
want a new syntax. I demonstrated that close approximations of some of the mentioned syntaxes were possible in the language already, and while I appreciate that your preferred syntax is not on that list, I remain unconvinced that its purported benefits outweigh what I perceive to be its drawbacks.
Just out of curiosity, what do you see as the drawbacks? The ones that come to my mind are: * people who want late binding to be standard will be disappointed (but that will be true of any solution) * requires changes to Python's parser, to allow unary-& (but that will probably be very simple) * requires charges to Python's compiler, to allow for some sort of late-binding semantics (thunks?) (but that will probably be very hard) * requires people to learn one more feature (so newbies will still be confused that def f(x=[]) doesn't behave as they expect). -- Steven D'Aprano