What is a function parameter =[] for?

BartC bc at freeuk.com
Thu Nov 19 12:30:43 EST 2015


On 19/11/2015 16:01, Steven D'Aprano wrote:
> On Fri, 20 Nov 2015 12:19 am, BartC wrote:

> You know, for somebody who claims to design and implement your own
> languages, you sometimes go to a remarkable effort to claim to be a dummy.
> You write your own interpreter, but can't understand early versus late
> binding? I don't think so.

No I don't; so? Maybe my interpreter can do its thing without being 
aware that what it's doing has been called 'late binding' or 'early 
binding' by someone else.

At least its default values work as expected! (And they can also be 
applied to existing external functions. Even C API functions where the 
implementation doesn't support these features.

So if an argument is missing, it applies the default I specify in its 
place. It's that simple.)

> I understand that the simplest things can be perplexing if you look at them
> the wrong way. But we've explained multiply times now, or at least tried to
> explain, that the argument default is a single object. That is blindingly
> obvious once you look at it the right way, and it is a nice, clean design.

I can understand now how it works as it does. But I still think it is 
unintuitive. A language design could have chosen to make it work however 
it liked.

> There's no need to introduce extra modes where code has to be stored away
> to be evaluated later (apart from the body of the function itself).
> Everything works the same way: assignment always evaluates a result and
> binds it to the name, whether that assignment is in a parameter list or
> not.
>
> If you insist on thinking about it in terms of how C or Pascal work, of
> course you will confuse yourself. The argument default is evaluated when
> the function is created, and the resulting object is stored away for later
> use, inside the function. That is clean and easy to understand.
>
> I'm not saying that the behaviour with mutable defaults

The whole concept of 'mutable' default is alien to me. A default is just 
a convenient device to avoid having to write:

   fn(0) or fn("") or fn([])

You just write fn() instead. But it shouldn't come at the cost of 
completely different semantics! Because then it can't really be called a 
default value at all.

  isn't surprising to
> somebody coming from a completely different paradigm. I was surprised by it
> too, the first time I got bitten.

So you didn't bother reading the LRM either!

> py> def demo_const(x, y=[]):
> ...     return x + len(y)

> Exactly as you should expect. Where you run into trouble is when the default
> value is NOT a constant:
>
> py> def demo_variable(x, y=[]):
> ...     y.append(1)
> ...     return x + len(y)

Sorry, what is the default value in each of these? As the first lines of 
the defintions look identical apart from the function names.

> ...
> py> demo_variable(5)
> 6
> py> demo_variable(5)
> 7
> py> demo_variable(5)
> 8
>
>
> If you modify the value, the value will be modified. Why are you surprised
> by this?

Which value is being modified? The []?

>> And most often that constant is 0, "" or an empty list.
>>
>> You want these very common examples to /just work/ instead of going to
>> lengths trying to explain why they don't.
>
> Ah, the good-old "I shouldn't have to think to understand programming" model
> of programming. Because that works so well.

It works well when sharing code because not everyone understands things 
at the same level.

>> Maybe you can wrap the entire module inside a function? Other than a bit
>> at the end that calls that function. Does that solve the global lookup
>> problem?
>
> No.

Why not?

>
>>> When you deal with mutable objects, you have to expect them to mutate.
>>> The whole point of mutability is that their value can change.
>>
>> That [] doesn't look like an object that could change.
>
> Of course it does.

You've lost me know.

Are you saying that:

   a=[]

why sometimes not assign an empty list, because that [] could have been 
modified?

It is a list literal, like int literals, float literals,
> string literals and the rest.

Another surprise? Literals by definition can't change:

def fn():
	a=[10,20,30]
	a.append(999)

I would hope that a is set to [10,20,30] at each entry to the function!

>> You presumably think differently because you have some inside knowledge
>> of how Python works, and know that that [] undergoes a one-time
>> assignment to a local, persistent 'default' variable where it's value
>> can indeed by changed. (Thanks to another Python feature where an
>> assignment is a very shallow copy of an object.) And it is that volatile
>> variable that is the actual default.
>
> Assignments are not copies at all.

if you write A=B then something of B needs to have been copied into A, 
even if it's just the reference that B contains. Otherwise it would be 
difficult to get A to refer to the same object as B.

-- 
Bartc



More information about the Python-list mailing list