Late-binding of function defaults (was Re: What is a function parameter =[] for?)

Chris Angelico rosuav at gmail.com
Wed Nov 25 08:24:32 EST 2015


On Wed, Nov 25, 2015 at 11:25 PM, Antoon Pardon
<antoon.pardon at rece.vub.ac.be> wrote:
>> But there's a big difference between those who guess wrong from a position
>> of ignorance, and then make an honest attempt to understand the behaviour
>> and why it actually does make sense and is even sometimes useful (even if
>> they don't like it), and those people who insist that it is nonsensical,
>> magical and "bizarre".
>
> There is an equally big difference between trying to explain what is going
> on and insisting that what is going on is not bizarre.

There is also a big difference between finding that something doesn't
match your expectations and declaring that it is "bizarre", which
implies that it makes no sense *to anyone*. What we've been pointing
out to you is that Python's way *does* make sense - just a different
sense from the one you're expecting.

There are many design decisions in programming languages. I've used
languages that have myriad keywords, multiple levels of keywords (SQL
is a shocking mess in that area), or no keywords at all (in REXX, you
can legally write "if if then then; else else", and it interprets
three of those as structure-defining and three as identifiers). I've
used languages where everything's a statement, even basic arithmetic.
Some languages make you declare your local variables, while others
have you declare your globals instead. These are all viable choices,
and they all make sense. The languages are internally coherent. I
would not call any of them "bizarre", with the possible exception of
DeScribe Macro Language, and even that's not too hard to get your head
around. (I wouldn't want to use it for any sort of general
programming, though. Its sole value is manipulating the DeScribe Word
Processor, and if you were to use it for something else, you'd have to
expand the language lexicon. There's no system of extensibility.)

Expanding on one of those examples, here are three ways that you can
distinguish between local/nonlocal/global variables/names/etc:

/* C++: Declare everything at a specific scope. */
int global_variable = 1;

struct outer_scope
{
    int instance_variable;
    void inner_scope()
    {
        int local_variable = 3;
    }
};

/* PHP: Declare your globals, otherwise they're local. */
$global_variable = 1;
function outer_function()
{
    global $global_variable;
    $local_variable = 2;
    /* I don't trust PHP's nested functions. */
}

# Python: Declare any globals you want to rebind.
global_name = 1
def outer_function():
    nonlocal_name = 2
    def inner_function():
        global global_name
        local_name = 3

There are variations on these, too (like ECMAScript's "declare and
it's function local, else it's an attribute of the global object").
Anyway. Point is, each of these systems is internally consistent, and
in each one, you can explain in a single sentence what the rule is.
Not one of these is bizarre, but I do completely understand that
anyone who has experience with just one of them _would_ find either of
the others confusing at first. "Wait, why do you need to declare this
as global, but not that?" "You're not assigning to that one, so you
don't need to declare it."

If you want to call Python's system "bizarre", you have to show more
than just that your expectations weren't matched by the language. You
have to show that Python lacks internal sense or consistency. You
have, so far, not shown anything of the kind, ergo we are continuing
to insist that Python is NOT bizarre.

ChrisA



More information about the Python-list mailing list