[Python-ideas] fixing mutable default argument values

Jan Kanis jan.kanis at phil.uu.nl
Wed Feb 7 16:53:57 CET 2007


Other non-python stuff is taking my time, but I'll reply to this anyway.  
Better late than never (in this case).

On Thu, 01 Feb 2007 16:19:00 +0100, Lucio Torre <lucio.torre at gmail.com>  
wrote:

> On 1/31/07, Jan Kanis <jan.kanis at phil.uu.nl> wrote:
>> >
>> > Isnt the other argument the fact that always re evaluating will bring
>> > similar gotchas?
>>
>> IMO, it won't. Caching will have to be implemented in a different way,  
>> but
>> that wouldn't really be a gotcha (except for python 2.x programmers who
>> didn't read the "what's new in python 3.0")
>>
>
> Maybe is better to annoy newbies that didnt read the python FAQ than
> seasoned python 2.x programmers! :)

That statement I can agree with, but it isn't really applicable here. The  
applicable statement reads: "Maybe it's better to annoy newbies that  
didn't read the python FAQ than python 2.x programmers who don't know  
anything about 3.0 and assume it's just another new version of python."
And I don't agree with that one. :)

>>  If the
>> function depends on other state I'd imagine that most of the time you'd
>> want a change in state to be reflected in the functions default value.
>>
>> example:
>> def foo(x = exec_sql("SELECT someval FROM defaults_table WHERE
>> some_expr")):
>>     # do something
>>
>
> i was thinking more in the lines of the case when you dont want the
> default to change because something has changed.

Then don't make the default depend on something you're going to change.

Well, what this is really about is about closure vars changing when the  
outer scope changes them instead of the value of the closure vars being  
captured by the new lexical scope. This has been proposed before (to  
change this behaviour on closure variables in general) and rejected.  
(though I am in favour of it)
Python is a late binding language in just about everything, and that is  
considered to be a good thing. The point you're making is exactly the  
early-vs-late binding discussion.

> I still think this would be optimizing towards the case where you
> should put the code in the body. What if i want a static default
> parameter, never to change, but i want to compute it at compile time?
> Should i need to use extra syntax for that? Isnt this case more common
> than the others? Something like:
>
> def foo( pixels = (640*480) ): pass
>
> Should overriding '*' change that default value? (can you do that in
> python3k? i think you cant in 2.x)

I'm not really sure if you can either. Anyway, the only cases I can think  
of when this makes sense is when there's a bug in '*' and you want to  
patch it, or if you're overloading '*' to work with other values, without  
changing the meaning for ints. In both of these cases it would be a good  
resp. neutral thing to late-bind '*'

> On the other hand, i think that learning about compile time and run
> time is a great thing and should be encouraged.

Yup. But let's not fill the language with gotchas for the newbies to find  
and learn from :)

>> > And having code that is invoked every time a function is called..
>> > shouldnt the place for this be the function body?
>>
>> The only reason to answer 'yes' is because it is what you're currently
>> used to.
>
> Im not only used to it, i like it :)

You'll get to like the new way :)

>> If I see a function with a default argument of [], I expect it to
>> use an empty list when I call it without the argument.
>>
>
> That is true. I hate that. But i still like it better than the other
> cases. This can be learnt easily and gives you the power to do
> everything the other solutions have. The other solutions require more
> syntax and more learning to achieve the same. Id love to find a
> solution for this, but this options dont seem like one.

Please note that I'm not in favour of any of the possible new syntaxes, I  
am only in favour of changing the semantics without new syntax (cf the  
pre-pep).
Since many newbie python programmers run into this, it seems that it is  
easier to learn that python evaluates the default expressions at calltime,  
because that is what the rest of python makes the newbies expect when they  
first try it. So for newbies, there would actually be less learning  
involved.
You will have to remember this change when you start using py 3.0, but  
this won't be the only thing to remember. And there are still several  
other ways to make some python code evaluate the expression at deftime.

>> Having code that is eval'd when the function is defined, shouldn't the
>> place for this be outside the function definition?
>
> i dont know, "def fname (...):" is executed when the code block is
> executed (creating the function object), and the body is executed when
> the function is called. So having a statement that has both compile
> time and run time effects is kind of messy.

As the body is part of the def statement, the def is already doing exactly  
that (being both compile/def time and run/call time). Consider the ...'s  
to be part of the function body in the new semantics. Instead of part of  
the code in a def being executed at deftime and part at calltime,  
everything is just run at calltime. There are some pretty large warnings  
in the docs about this distinction currently, they can be taken out.

> I hope im still making sense and not playing out of my league, but
> thats just my 2c.
>
> Lucio.


- Jan



More information about the Python-ideas mailing list