Re: [Python-ideas] parameter omit

"Aaron Brady" <castironpi@comcast.net> wrote:
Should I send you my 486 laptop so that you can have access to a Python interpreter? Because I really can't see how you being ignorant of the arguments to a standard library function in any way supports your case. Further, if you always use 'None' as the default for functions being called, then you can get things like this... class WebRetrieveElement: hook = None filename = None def netretrieveNew( self ): filename= self.filename or ParamDefault hook= hasattr( self,'hook' ) and self.hook or ParamDefault urlretrieve( self.url, filename, hook ) def netretrieveBest(self): urlretrieve(self.url, self.filename, self.hook) And look at that. I define two class level variables and all of a sudden the implementation of netretrieveBest gets a trivial implementation (though it breaks netretrieveNew, which uses a generally frowned upon mechanism that fails when filename and hook are None). But no, lets add a completely useless instance of object so that people can pass silly default arguments like ParamDefault that is a bazillion times more confusing than what Python users have been using for 15 years; None. - Josiah

No thank you. Your example is sufficient. Well-crafted at that. Good example. Imagine with me if you will. Say I -am- "ignorant of the arguments to a standard library function". But say they aren't published in help(). Then that breaks yours and we have two broken examples. Great lot of good that did you. Say the default is not None; but a class callback. Say it is a default string for a join delimiter somewhere. Fine examples are imaginary numbers, the function string.split, file([bufsize]), int([radix]), list.sort([cmp]), etc. Pretty much anywhere you see the [] brackets in the documentation. These default values are obvious, and further, None is always a good guess. Answer this one carefully: Have you asserted that defaults are -always- available and published, in the standard library as well as elsewhere? Could one extra value in __builtins__ already be worth all our third-parties' time who could relax and get along? It'll bring world peace. But sure. Send your laptop on over. I'll pay on delivery. Sincerely, That Newsgroup Jerk

Your stewardship is remarkable. But in the case I mention, the costs aren't worth mention. It's an outstanding case, for clear, cost-free, net benefit. Say the parameter is required to be callable. `None' will not suffice. The strongest case against me is that I enable lazy programmers to make assignments in the function declaration. That's worth bringing up. OTOH, what if None is the wrong default? 2.4 Built-in Constants A small number of constants live in the built-in namespace. They are: False - The false value of the bool type. New in version 2.3. True - The true value of the bool type. New in version 2.3. None - The sole value of types.NoneType. None is frequently used to represent the absence of a value, as when default arguments are not passed to a function. NotImplemented - Special value which can be returned by the ``rich comparison'' special methods (__eq__(), __lt__(), and friends), to indicate that the comparison is not implemented with respect to the other type. Ellipsis - Special value used in conjunction with extended slicing syntax. DefaultArgument - Special value used in remaining cases of default arguments where None is not what is intended. Does one complain about Ellipsis? No, it's useful. Comes in handy at just the right times. And furthermore, this proposal isn't entirely without precedent.

Em 11/05/2007, às 05:43, Aaron Brady escreveu:
And furthermore, this proposal isn't entirely without precedent.
Ok, we got the idea so let's start voting then :) i'm like -1000 on it... or def vote(who, value=-1000): ... i'm like: vote(santagada@gmail.com) :) -- Leonardo Santagada santagada@gmail.com

On Fri, 11 May 2007 10:43:18 +0200, Aaron Brady <castironpi@comcast.net> wrote:
There are some hidden costs you haven't mentioned yet: 1) It's another paragraph in the manual. 2) If DefaultArgument is just a normal object in the builtin namespace, without any interpreter magic every function using default values would have to use some logic to recognize DefaultArgument and do the right thing. If there is interpreter magic that'll be more magic, and another section in the manual to explain that. (apart from magic in itself being bad) A small manual addition wouldn't be a problem on its own, but proposals that easily fix some use case with just a single paragraph manual addition pass by every other week. If they'd all be accepted we'd be saving ourselves a lot of trouble by switching to Perl immediately. More manual means more language complexity, another little step for people learning python, and another page of brain cell usage for anyone using Python. In short, any new addition has to have a *lot* of utility to be acceptable, or else it wil lead to the way of the Perl side. - Jan Oh, and having jerks around is an unfortunate & unintended side effect of having people in the mailing list. I'd be interested if you had any ideas to diminish the problem, though. <wink>

Not only does the OP's proposal (me) exonerate programmers who have screwed up before, those who have neglected to use None for defaults, and who chose meaningful ones instead, but encourages them to continue to choose it, and frees them from checking the parameter later.
Note DefaultArg needs never get referenced literally in declarations, only in calls. def ghi( j=None, k=None, l=None ): if j is None: j= Something if k is None: k= Something2 if l is None: l= Something3 No. Here, I do it all at once. def ghi( j=Something, k=Something2, l=Something3 ): Calls like ghi( MyThing ) still work, as does: ghi( MyThing, l=MyThing3 ). Everybody's on board so far and nothing's changed. Omissions, positional, and keyword arguments still work as we've grown to know and love. What we can do, is always know the parameter. The change is to know the default value in every situation. It's always DefaultArg. ghi( MyThing, DefaultArg, Mything3 ) as well as ghi( DefaultArg, MyThing2 ) Nothing breaks; everything that used to work still does. There's no magic in my proposal, no more than defaults create in the first place. Functions get the assignments done for them; they take no extra logic on their own. It's completely backwards compatible. No question there! But you get new abilities too, for the price of something that's unobtrusive and blends right in. To address Jewett, default arguments -are- built into bytecode. The wrapper takes a single memory address comparison on a per-argument basis. It could get expensive, but at least compare it to looking up values in dictionaries, which is quite common.
If they're not defined, as in C code, then they're always last, or couldn't be called like you guys want to anyway. Raise the usual exception anyway.
In short, any new addition has to have a *lot* of utility to be acceptable, or else it wil lead to the way of the Perl side.
Agreed entirely. You mean, like this? Who brings up the manual? Good. Document something. Your names in lights, I can see it now. I'll write the PEP, but first stop pointing out drawbacks and motivate me. Wink( DefaultArg ). P.S. people. A little louder and stronger could suffice. "Let me hear it son. Costs and benefits. Bottom line. Assets or liabilities?" Then put your feet up.

On 5/11/07, Aaron Brady <castironpi@comcast.net> wrote:
Maybe I'm missing something here... But why would someone not use the latter syntax unless the value must be calculated when the function is called, as opposed to when the function is defined? In such cases, None fits the bill. (Default arguments are evaluated at function definition.) Calls like ghi( MyThing ) still work, as does:
IMHO this is far less readable than using keyword arguments and omitting those arguments for which you'd like to use the default value. I personally like the "keyword-only arguments" PEP (3102) because it could help make function calls more readable. Perhaps we could learn from experience? I've recently had to automate Excel with Python and used the COM interface. In COM, there is a value called "Missing" which is passed to functions when no value should be passed for an argument - similar to your DefaultArg. This leads to code like this (C# code examples): http://msdn2.microsoft.com/en-us/library/aa168343(office.11).aspx (straight from the online MSDN) MenuBarItem = MainMenuBar.Controls.Add( Office.MsoControlType.msoControlPopup, Type.Missing, Type.Missing, Type.Missing, true); And that was not a far-fetched example - here is an extreme example: http://blogs.ittoolbox.com/visualbasic/evolution/archives/importing-unformat... Excel.Application excelApp = new Excel.ApplicationClass(); Excel.Workbook thisWorkbook = excelApp.Workbooks.Open(strFileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing); IMO this is horrendous. Horrible. Eye-gouging. I'd rather write machine code in hex. - Tal

_____ From: Tal Einat [mailto:taleinat@gmail.com] Sent: Friday, May 11, 2007 3:02 PM To: python-ideas@python.org Cc: Aaron Brady Subject: Re: [Python-ideas] parameter omit On 5/11/07, Aaron Brady <castironpi@comcast.net> wrote: Note DefaultArg needs never get referenced literally in declarations, only in calls. def ghi( j=None, k=None, l=None ): if j is None: j= Something if k is None: k= Something2 if l is None: l= Something3 No. Here, I do it all at once. def ghi( j=Something, k=Something2, l=Something3 ): Maybe I'm missing something here... But why would someone not use the latter syntax unless the value must be calculated when the function is called, as opposed to when the function is defined? In such cases, None fits the bill. (Default arguments are evaluated at function definition.) Calls like ghi( MyThing ) still work, as does: ghi( MyThing, l=MyThing3 ). Everybody's on board so far and nothing's changed. Omissions, positional, and keyword arguments still work as we've grown to know and love. What we can do, is always know the parameter. The change is to know the default value in every situation. It's always DefaultArg. ghi( MyThing, DefaultArg, Mything3 ) as well as ghi( DefaultArg, MyThing2 ) IMHO this is far less readable than using keyword arguments and omitting those arguments for which you'd like to use the default value. I personally like the "keyword-only arguments" PEP (3102) because it could help make function calls more readable. Perhaps we could learn from experience? I've recently had to automate Excel with Python and used the COM interface. In COM, there is a value called "Missing" which is passed to functions when no value should be passed for an argument - similar to your DefaultArg. This leads to code like this (C# code examples): http://msdn2.microsoft.com/en-us/library/aa168343(office.11).aspx (straight from the online MSDN) MenuBarItem = MainMenuBar.Controls.Add( Office.MsoControlType.msoControlPopup, Type.Missing, Type.Missing, Type.Missing, true); And that was not a far-fetched example - here is an extreme example: http://blogs.ittoolbox.com/visualbasic/evolution/archives/importing-unformat ted-excel-sheets-into-sql-server-2000-using-net-part-i-7501 Excel.Application excelApp = new Excel.ApplicationClass(); Excel.Workbook thisWorkbook = excelApp.Workbooks.Open(strFileName,Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing); IMO this is horrendous. Horrible. Eye-gouging. I'd rather write machine code in hex. - Tal

Ok, this isn't working to get my idea over. There's something wrong with somebody, and it's simplest to assume its me. Probably inexperience in posting. Not to mention, I have no idea who I'm talking to, or what the local dialect is. (Sorry about the blank message too... wrong keystroke.) Tal's examples don't contradict me. In his, I call:
Traditional function call. Calls still will work the way they do today. You have -extra- flexibility, not less, sir. I add zero requirements. Please let me repeat. Nothing breaks.

On 5/11/07, Aaron Brady <castironpi@comcast.net> wrote:
carefully: Have you asserted that defaults are -always- available and published, in the standard library as well as elsewhere?
Of course not. Sometimes the real default value doesn't really exist yet, because it is constructed after the function gets called with 'None'. Your proposal doesn't change this. When the default should be introspectable and isn't, this is usually because the function was written in C, and the author wasn't careful to add the proper docstring tagging. If they aren't supporting docstrings yet, they won't bother to support your new object either -- so it has to be done either at the interpreter level or with a wrapper function. The costs in the interpreter would be significant, both in complexity (a special case) and in speed (that particular loop is tight enough that any change can have unexpected results by changing cache performance). The wrapper solution seems good enough to me; it doesn't slow things down unless you use it. You can even automate it with monkey-patching if you like.
I am pleasantly surprised to get 24 hour response from a vendor, even when I (or, rather, my employer) has paid for that support. But in this case, you actually did get a fairly quick response; it just wasn't what you wanted, because the responders did *not* think it was likely to be a good idea, and you weren't willing to listen to the alternative solutions they proposed.
Could one extra value in __builtins__ already be worth all our third-parties' time who could relax and get along?
If you compile your own local copy, then sure. If you want it in the worldwide distribution, then probably not; backwards compatibility means that it will change only at a bureaucratic pace. As a point of comparison, your proposal would actually be a larger change than decorators, for a less frequent use case. Decorators were agreed to in theory for 2.3 (around 2002/2003), but concerns about how to do it right kept them out until 2.4. Class decorators were still not included (despite a working implementation which was actually a bit simpler) because there was a chance they wouldn't be needed, and adding things is easier than taking them back out. Class decorators have now been approved for Python 2.6, which will probably be available some time next year. -jJ

And while I'm at it and thinking clearly, with cool weather and open doors, the basic problem here, underlying and distilled, is that None is serving double-duty. I've had a feeling so since month two. It's used to signal an absence of a value. But there are two distinct situations in which it's needed. One for values, two for function calls. You could always require all parameter defaults to equal `None'. But since they're not, take this. DefaultArg = object()

On 5/11/07, Aaron Brady <castironpi@comcast.net> wrote:
Yes. When None appears in a parameter list (or an argument list, at the calling site), it might really be a sentinel for something else, and that is a wart.
You could always require all parameter defaults to equal `None'. But since they're not, take this.
DefaultArg = object()
Yes; this is used when None actually is a valid and meaningful value. I don't see a good way to *always* use this idiom though, because (1) If DefaultArg is a pre-existing object, then there will be times when it is valid and meaningful data -- such as when introspecting. (2) Creating it afresh is a bit of boilerplate that we wouldn't want to require when it isn't really needed. sentinel=object() def f(val=sentinel): if val is sentinel: And note that the creation can't be inline, such as def f(val=object()): or there wouldn't be any good way to test for it. Adding a keyword to do that def f(val=object()): if defaulted val: would probably be a good idea. (I don't think it would get used often enough to justify the costs of a change, but there would be a clear benefit to include in the cost-benefit calculations.) -jJ

On 5/12/07, Aaron Brady <castironpi@comcast.net> wrote:
Can we do:
Sure, but then people have to import sentinel before using it to call your function.
? How common are non-None default values?
Pretty common. They are usually (but not always) a zero of some sort (0, "", {}, []) which *could* be done with the None and type annotations in Py3. -jJ

I've gone through quite a few moods, attitudes, reading this. If you do, seek help; I am a miscreant by profession. Ranging from audacity and awe, to indignance, I have found the newsgroup on the whole to be reasonable yet stubborn. Expect me to take the other side soon. Erratic, fickle, go for it. Jewett's idea,
if defaulted val:
-is- very Pythonic, blending in much better than mine. Mine isn't after all but I don't see why or how. Too bad too; it's a beaut' as ideas go.
Sure, but then people have to import sentinel before using it to call your function.
Good. Fine. From constants import True, None, Sentinel. I see in contrast. You know how many cigarettes I'd get for free if I saved all my C-Note Camelbucks? More later, if at all.

<snip>
? How common are non-None default values? </snip>
Quoting myself from http://mail.python.org/pipermail/python-3000/2007-February/005704.html ([Python-3000] pre-PEP: Default Argument Expressions), when I generated statistics related to this subject:
So, I'd say that they're pretty frequent, with at least 41.5% of all std lib default values being non-None. - Chris Rebert

No thank you. Your example is sufficient. Well-crafted at that. Good example. Imagine with me if you will. Say I -am- "ignorant of the arguments to a standard library function". But say they aren't published in help(). Then that breaks yours and we have two broken examples. Great lot of good that did you. Say the default is not None; but a class callback. Say it is a default string for a join delimiter somewhere. Fine examples are imaginary numbers, the function string.split, file([bufsize]), int([radix]), list.sort([cmp]), etc. Pretty much anywhere you see the [] brackets in the documentation. These default values are obvious, and further, None is always a good guess. Answer this one carefully: Have you asserted that defaults are -always- available and published, in the standard library as well as elsewhere? Could one extra value in __builtins__ already be worth all our third-parties' time who could relax and get along? It'll bring world peace. But sure. Send your laptop on over. I'll pay on delivery. Sincerely, That Newsgroup Jerk

Your stewardship is remarkable. But in the case I mention, the costs aren't worth mention. It's an outstanding case, for clear, cost-free, net benefit. Say the parameter is required to be callable. `None' will not suffice. The strongest case against me is that I enable lazy programmers to make assignments in the function declaration. That's worth bringing up. OTOH, what if None is the wrong default? 2.4 Built-in Constants A small number of constants live in the built-in namespace. They are: False - The false value of the bool type. New in version 2.3. True - The true value of the bool type. New in version 2.3. None - The sole value of types.NoneType. None is frequently used to represent the absence of a value, as when default arguments are not passed to a function. NotImplemented - Special value which can be returned by the ``rich comparison'' special methods (__eq__(), __lt__(), and friends), to indicate that the comparison is not implemented with respect to the other type. Ellipsis - Special value used in conjunction with extended slicing syntax. DefaultArgument - Special value used in remaining cases of default arguments where None is not what is intended. Does one complain about Ellipsis? No, it's useful. Comes in handy at just the right times. And furthermore, this proposal isn't entirely without precedent.

Em 11/05/2007, às 05:43, Aaron Brady escreveu:
And furthermore, this proposal isn't entirely without precedent.
Ok, we got the idea so let's start voting then :) i'm like -1000 on it... or def vote(who, value=-1000): ... i'm like: vote(santagada@gmail.com) :) -- Leonardo Santagada santagada@gmail.com

On Fri, 11 May 2007 10:43:18 +0200, Aaron Brady <castironpi@comcast.net> wrote:
There are some hidden costs you haven't mentioned yet: 1) It's another paragraph in the manual. 2) If DefaultArgument is just a normal object in the builtin namespace, without any interpreter magic every function using default values would have to use some logic to recognize DefaultArgument and do the right thing. If there is interpreter magic that'll be more magic, and another section in the manual to explain that. (apart from magic in itself being bad) A small manual addition wouldn't be a problem on its own, but proposals that easily fix some use case with just a single paragraph manual addition pass by every other week. If they'd all be accepted we'd be saving ourselves a lot of trouble by switching to Perl immediately. More manual means more language complexity, another little step for people learning python, and another page of brain cell usage for anyone using Python. In short, any new addition has to have a *lot* of utility to be acceptable, or else it wil lead to the way of the Perl side. - Jan Oh, and having jerks around is an unfortunate & unintended side effect of having people in the mailing list. I'd be interested if you had any ideas to diminish the problem, though. <wink>

Not only does the OP's proposal (me) exonerate programmers who have screwed up before, those who have neglected to use None for defaults, and who chose meaningful ones instead, but encourages them to continue to choose it, and frees them from checking the parameter later.
Note DefaultArg needs never get referenced literally in declarations, only in calls. def ghi( j=None, k=None, l=None ): if j is None: j= Something if k is None: k= Something2 if l is None: l= Something3 No. Here, I do it all at once. def ghi( j=Something, k=Something2, l=Something3 ): Calls like ghi( MyThing ) still work, as does: ghi( MyThing, l=MyThing3 ). Everybody's on board so far and nothing's changed. Omissions, positional, and keyword arguments still work as we've grown to know and love. What we can do, is always know the parameter. The change is to know the default value in every situation. It's always DefaultArg. ghi( MyThing, DefaultArg, Mything3 ) as well as ghi( DefaultArg, MyThing2 ) Nothing breaks; everything that used to work still does. There's no magic in my proposal, no more than defaults create in the first place. Functions get the assignments done for them; they take no extra logic on their own. It's completely backwards compatible. No question there! But you get new abilities too, for the price of something that's unobtrusive and blends right in. To address Jewett, default arguments -are- built into bytecode. The wrapper takes a single memory address comparison on a per-argument basis. It could get expensive, but at least compare it to looking up values in dictionaries, which is quite common.
If they're not defined, as in C code, then they're always last, or couldn't be called like you guys want to anyway. Raise the usual exception anyway.
In short, any new addition has to have a *lot* of utility to be acceptable, or else it wil lead to the way of the Perl side.
Agreed entirely. You mean, like this? Who brings up the manual? Good. Document something. Your names in lights, I can see it now. I'll write the PEP, but first stop pointing out drawbacks and motivate me. Wink( DefaultArg ). P.S. people. A little louder and stronger could suffice. "Let me hear it son. Costs and benefits. Bottom line. Assets or liabilities?" Then put your feet up.

On 5/11/07, Aaron Brady <castironpi@comcast.net> wrote:
Maybe I'm missing something here... But why would someone not use the latter syntax unless the value must be calculated when the function is called, as opposed to when the function is defined? In such cases, None fits the bill. (Default arguments are evaluated at function definition.) Calls like ghi( MyThing ) still work, as does:
IMHO this is far less readable than using keyword arguments and omitting those arguments for which you'd like to use the default value. I personally like the "keyword-only arguments" PEP (3102) because it could help make function calls more readable. Perhaps we could learn from experience? I've recently had to automate Excel with Python and used the COM interface. In COM, there is a value called "Missing" which is passed to functions when no value should be passed for an argument - similar to your DefaultArg. This leads to code like this (C# code examples): http://msdn2.microsoft.com/en-us/library/aa168343(office.11).aspx (straight from the online MSDN) MenuBarItem = MainMenuBar.Controls.Add( Office.MsoControlType.msoControlPopup, Type.Missing, Type.Missing, Type.Missing, true); And that was not a far-fetched example - here is an extreme example: http://blogs.ittoolbox.com/visualbasic/evolution/archives/importing-unformat... Excel.Application excelApp = new Excel.ApplicationClass(); Excel.Workbook thisWorkbook = excelApp.Workbooks.Open(strFileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing); IMO this is horrendous. Horrible. Eye-gouging. I'd rather write machine code in hex. - Tal

_____ From: Tal Einat [mailto:taleinat@gmail.com] Sent: Friday, May 11, 2007 3:02 PM To: python-ideas@python.org Cc: Aaron Brady Subject: Re: [Python-ideas] parameter omit On 5/11/07, Aaron Brady <castironpi@comcast.net> wrote: Note DefaultArg needs never get referenced literally in declarations, only in calls. def ghi( j=None, k=None, l=None ): if j is None: j= Something if k is None: k= Something2 if l is None: l= Something3 No. Here, I do it all at once. def ghi( j=Something, k=Something2, l=Something3 ): Maybe I'm missing something here... But why would someone not use the latter syntax unless the value must be calculated when the function is called, as opposed to when the function is defined? In such cases, None fits the bill. (Default arguments are evaluated at function definition.) Calls like ghi( MyThing ) still work, as does: ghi( MyThing, l=MyThing3 ). Everybody's on board so far and nothing's changed. Omissions, positional, and keyword arguments still work as we've grown to know and love. What we can do, is always know the parameter. The change is to know the default value in every situation. It's always DefaultArg. ghi( MyThing, DefaultArg, Mything3 ) as well as ghi( DefaultArg, MyThing2 ) IMHO this is far less readable than using keyword arguments and omitting those arguments for which you'd like to use the default value. I personally like the "keyword-only arguments" PEP (3102) because it could help make function calls more readable. Perhaps we could learn from experience? I've recently had to automate Excel with Python and used the COM interface. In COM, there is a value called "Missing" which is passed to functions when no value should be passed for an argument - similar to your DefaultArg. This leads to code like this (C# code examples): http://msdn2.microsoft.com/en-us/library/aa168343(office.11).aspx (straight from the online MSDN) MenuBarItem = MainMenuBar.Controls.Add( Office.MsoControlType.msoControlPopup, Type.Missing, Type.Missing, Type.Missing, true); And that was not a far-fetched example - here is an extreme example: http://blogs.ittoolbox.com/visualbasic/evolution/archives/importing-unformat ted-excel-sheets-into-sql-server-2000-using-net-part-i-7501 Excel.Application excelApp = new Excel.ApplicationClass(); Excel.Workbook thisWorkbook = excelApp.Workbooks.Open(strFileName,Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing, Type.Missing); IMO this is horrendous. Horrible. Eye-gouging. I'd rather write machine code in hex. - Tal

Ok, this isn't working to get my idea over. There's something wrong with somebody, and it's simplest to assume its me. Probably inexperience in posting. Not to mention, I have no idea who I'm talking to, or what the local dialect is. (Sorry about the blank message too... wrong keystroke.) Tal's examples don't contradict me. In his, I call:
Traditional function call. Calls still will work the way they do today. You have -extra- flexibility, not less, sir. I add zero requirements. Please let me repeat. Nothing breaks.

On 5/11/07, Aaron Brady <castironpi@comcast.net> wrote:
carefully: Have you asserted that defaults are -always- available and published, in the standard library as well as elsewhere?
Of course not. Sometimes the real default value doesn't really exist yet, because it is constructed after the function gets called with 'None'. Your proposal doesn't change this. When the default should be introspectable and isn't, this is usually because the function was written in C, and the author wasn't careful to add the proper docstring tagging. If they aren't supporting docstrings yet, they won't bother to support your new object either -- so it has to be done either at the interpreter level or with a wrapper function. The costs in the interpreter would be significant, both in complexity (a special case) and in speed (that particular loop is tight enough that any change can have unexpected results by changing cache performance). The wrapper solution seems good enough to me; it doesn't slow things down unless you use it. You can even automate it with monkey-patching if you like.
I am pleasantly surprised to get 24 hour response from a vendor, even when I (or, rather, my employer) has paid for that support. But in this case, you actually did get a fairly quick response; it just wasn't what you wanted, because the responders did *not* think it was likely to be a good idea, and you weren't willing to listen to the alternative solutions they proposed.
Could one extra value in __builtins__ already be worth all our third-parties' time who could relax and get along?
If you compile your own local copy, then sure. If you want it in the worldwide distribution, then probably not; backwards compatibility means that it will change only at a bureaucratic pace. As a point of comparison, your proposal would actually be a larger change than decorators, for a less frequent use case. Decorators were agreed to in theory for 2.3 (around 2002/2003), but concerns about how to do it right kept them out until 2.4. Class decorators were still not included (despite a working implementation which was actually a bit simpler) because there was a chance they wouldn't be needed, and adding things is easier than taking them back out. Class decorators have now been approved for Python 2.6, which will probably be available some time next year. -jJ

And while I'm at it and thinking clearly, with cool weather and open doors, the basic problem here, underlying and distilled, is that None is serving double-duty. I've had a feeling so since month two. It's used to signal an absence of a value. But there are two distinct situations in which it's needed. One for values, two for function calls. You could always require all parameter defaults to equal `None'. But since they're not, take this. DefaultArg = object()

On 5/11/07, Aaron Brady <castironpi@comcast.net> wrote:
Yes. When None appears in a parameter list (or an argument list, at the calling site), it might really be a sentinel for something else, and that is a wart.
You could always require all parameter defaults to equal `None'. But since they're not, take this.
DefaultArg = object()
Yes; this is used when None actually is a valid and meaningful value. I don't see a good way to *always* use this idiom though, because (1) If DefaultArg is a pre-existing object, then there will be times when it is valid and meaningful data -- such as when introspecting. (2) Creating it afresh is a bit of boilerplate that we wouldn't want to require when it isn't really needed. sentinel=object() def f(val=sentinel): if val is sentinel: And note that the creation can't be inline, such as def f(val=object()): or there wouldn't be any good way to test for it. Adding a keyword to do that def f(val=object()): if defaulted val: would probably be a good idea. (I don't think it would get used often enough to justify the costs of a change, but there would be a clear benefit to include in the cost-benefit calculations.) -jJ

On 5/12/07, Aaron Brady <castironpi@comcast.net> wrote:
Can we do:
Sure, but then people have to import sentinel before using it to call your function.
? How common are non-None default values?
Pretty common. They are usually (but not always) a zero of some sort (0, "", {}, []) which *could* be done with the None and type annotations in Py3. -jJ

I've gone through quite a few moods, attitudes, reading this. If you do, seek help; I am a miscreant by profession. Ranging from audacity and awe, to indignance, I have found the newsgroup on the whole to be reasonable yet stubborn. Expect me to take the other side soon. Erratic, fickle, go for it. Jewett's idea,
if defaulted val:
-is- very Pythonic, blending in much better than mine. Mine isn't after all but I don't see why or how. Too bad too; it's a beaut' as ideas go.
Sure, but then people have to import sentinel before using it to call your function.
Good. Fine. From constants import True, None, Sentinel. I see in contrast. You know how many cigarettes I'd get for free if I saved all my C-Note Camelbucks? More later, if at all.

<snip>
? How common are non-None default values? </snip>
Quoting myself from http://mail.python.org/pipermail/python-3000/2007-February/005704.html ([Python-3000] pre-PEP: Default Argument Expressions), when I generated statistics related to this subject:
So, I'd say that they're pretty frequent, with at least 41.5% of all std lib default values being non-None. - Chris Rebert
participants (7)
-
Aaron Brady
-
Chris Rebert
-
Jan Kanis
-
Jim Jewett
-
Josiah Carlson
-
Leonardo Santagada
-
Tal Einat