[Python-Dev] q about default args

Michael Hudson mwh@python.net
22 Aug 2002 10:31:07 +0100


Stepan Koltsov <yozh@mx1.ru> writes:

> Hi, Guido, other Python developers and other subscribers.
> 
> 
> First of all, if this question was discussed here or somewhere
> else 8086 times, please direct me to discussion archives.

I doubt it's ever been discussed on python-dev.  Most people here know
a non-starter when they see one.

Hmm.  Well, they know this one's a non-starter :)

> I couldn't guess the keywords to search for in the python-dev archives
> as I haven't found the search page where to enter these keywords :-)

Just use google.  If python-dev is the most relavent place for the
discussion, the archives will be near the top of the results.

> The question is: To be or^H^H^H^H^H^H^H^H^H Why not evaluate default
> parameters of a function at THE function call, not at function def
> (as is done currenly)? For example, C++ (a nice language, isn't it? ;-)

No.

> ) evaluates default parameters at function call.
> 
[...]
> Implementation details:
> 
> Simple... 
> Add a flag to the code object, that means "evaluate default args".
> Compile default args to small code objects and store them where values
> for default args are stored in current Python (i.e. co_consts).

That's not where they're stored.

> When a function is called, evaluate the default args (if the above
> flag is set) in the context of that function. 

This could break code, you realise:

a = 1
def f(a, b=a):
    print a, b

[...]

I could go on, but I'm running out of steam...

> An alternative way to go (a little example... LOOK ON, PERSONALY, I
> LIKE IT ALLOT):

Fortunately or unfortunately, that makes little difference to the
direction of python development.

> ---
> 
> def f(x=12+[]):
> 	stmts
> 
> ===
> 
> compiled into something like:
> 
> 0: LOAD_CONST 1 (12)
> 1: BUILD_LIST 0
> 2: BINARY_ADD
> 3: STORE_FAST 0 (x)
> 4: # here code of stmts begin
> 
> in the case if 'x' was specfied, the code is executed instruction 4
> onword This should work perfectly, ideologically correct and I think
> even faster then current interpreter implementation.

You'd have fun with:

def f(a=1,b=2):
    print a, b

f(b=1)

here, no?

> 
> Motivation (he-he, the most difficult part of this letter):
> 
> 1. Try to import this module:
> 
> ---xx.py---
> 
> import math
> def func(a = map(lambda x: math.sqrt(x)):
> 	pass
> # there is no call to func
> 
> ===
> 
> This code does nothing but define a single function,
> but look at the execution time...

So don't do something that thick, then!

> 2. Currently, default arguments are like static function variables,
> defined in the function parameter list! That is wrong.

Says you.

> 4. Again: I dislike code like
> 
> ---
> 
> def f(l=None):
>     if l is None:
>         l = []
>     ...

Who elected you style guru of the universe?  

> 5. I asked my friend (also big Python fan): why the current
> behaviour is correct?  his answer was: "the curren behaviour is
> correct, becausethat is the way it was done in the first place :-)
> ..." I don't see any advantages of the current style, and lack of
> advantages is advantage of new style :-)

For better of for worse, people *do* write code that depends on
default function arguments being evaluated once, usually as a lazy way
of precomputing things, or as a cache.

> I hope, that the current state of things is a result of laziness (or is
> it "business"), not sabotage :-) .  and not an ideological decision. It
> isn't late to fix Python yet :-) 

Two points: 

1) I'm unconvinced this is a "fix"
2) I think it probably is too late.

Cheers,
M.

-- 
  You can lead an idiot to knowledge but you cannot make him 
  think.  You can, however, rectally insert the information, 
  printed on stone tablets, using a sharpened poker.        -- Nicolai
               -- http://home.xnet.com/~raven/Sysadmin/ASR.Quotes.html