Default Value

Rotwang sg552 at hotmail.co.uk
Sat Jun 22 13:19:31 EDT 2013


On 22/06/2013 03:01, I wrote:
> On 22/06/2013 02:15, Rick Johnson wrote:
>> [...]
>>
>> This is what should happen:
>>
>>      py> def foo(arg=[]):
>>      ...     arg.append(1)
>>      ...     print(arg)
>>      ...
>>      py> foo()
>>      [1]
>>      py> foo()
>>      [1]
>>      py> foo()
>>      [1]
>>
>> Yes, Yes, YES! That is intuitive! That is sane! Now, what if
>> we pass a reference to a mutable object? What then. Well, let's
>> see:
>>
>>      py> lst = range(5)
>>      py> lst
>>      [0, 1, 2, 3, 4]
>>      py> def foo(arg=lst):
>>      ...     arg.append(1)
>>      ...     print(arg)
>>      ...
>>      py> foo()
>>      [0, 1, 2, 3, 4, 1]
>>      py> foo()
>>      [0, 1, 2, 3, 4, 1, 1]
>>
>> That's fine. Because the object was already created OUTSIDE
>> the subroutine. So therefore, modifications to the mutable
>> are not breaking the fundamental of statelessness INSIDE
>> subroutines. The modification is merely a side effect, and
>> the subroutine is unconcerned with anything that exists
>> beyond it's own scope.
>>
>> IS ALL THIS REGISTERING YET? DO YOU UNDERSTAND?
>
> No, I don't. These two special cases are not sufficient for me to
> determine what semantics you are proposing for the general case. For
> example, what happens in the second example if lst is rebound? Does the
> default stay the same or does it change to the new value of lst? What
> about if you pass a call as a default argument, and then subsequently
> change the behaviour of the callable? Does the argument get re-evaluated
> every time foo() is called, or is the argument guaranteed to be the same
> every time? If the latter, what happens if the arguments type is
> modified (e.g. by changing one of its class attributes)? What about
> defining functions dynamically, with default arguments that are only
> known at runtime? Is there any way to avoid the second type of behaviour
> in this case? If so, how? If not, isn't that likely to prove at least as
> big a gotcha to people who don't know the rules of RickPy as the problem
> you're trying to solve?

Since you haven't answered this, allow me to suggest something. One 
thing that a language could do is treat default arguments as mini 
function definitions with their own scope, which would be the same as 
the scope of the function itself but without the function's arguments. 
In other words, in this alternative version of Python, the following

 >>> def f(x = <expression>):
...    <stuff>

would be equivalent, in actual Python, to this:

 >>> default = lambda: <expression>
 >>> sentinel = object()
 >>> def f(x = sentinel):
...    if x is sentinel:
...        x = default()
...    <stuff>

That would be something that could be implemented, and as far as I can 
tell it's consistent with the examples you've given of how you would 
like Python to work. Is this indeed the kind of thing you have in mind?




More information about the Python-list mailing list