On Fri, Apr 28, 2017 at 09:54:55AM +1000, Chris Angelico wrote:
> On Fri, Apr 28, 2017 at 9:21 AM, Steven D'Aprano <st...@pearwood.info> wrote:
> > What happens if you use this syntax in a top-level function rather
> > than a method? (Or a static method?)
> >
> > def function(x, y, x.attr):
> >     ...
> >
> > (And don't forget that behind the scenes, methods *are* functions.) What
> > would this syntax even mean?
> >
> >
> > Or if you use some other name other than the first parameter?
> >
> > def method(self, spam, foo.eggs):
> 
> Exactly the same thing as:
> 
> def function(*args):
>     x, y, x.attr = args
> 
> def method(*args):
>     self, spam, foo.eggs = args


Obviously we can define syntax to do anything we like, but what is the 
logical connection between the syntax and the semantics? What part of 
"function parameter list" suggests "assign attributes to arbitrary 
objects"?

Do we support arbitrary targets in their full generality?

def function(arg, 
        (name if name is not None else 
other).the_object.attr[0].method(foo)['key'].argument
        ):
    ...

Of course, there are lots of things which are technically allowed but if 
someone is silly enough to do it, we say "don't do that". However, even 
the simple case is problematic:

def trigonometry(x, y, math.pi)

We could make that parameter declaration have the side-effect of 
assigning to math.pi, but that's a pretty surprising change to function 
declarations. Everything else declared inside a parameter list is local 
to the function: parameters themselves are local variables, default 
values and annotations are stored in the function not externally.

The only thing which is not local is that default values may be 
arbitrary expressions, which may have side-effects, but that is not a 
declaration, its an expression evaluated for its value.

What's the connection between parameter declarations and this sort of 
external side-effect? It seems pretty arbitrary to be a built-in part of 
the language, like having

def function(x)

automatically print x, or pickle it and upload the file to the cloud.

(Obviously the side-effect doesn't occur until the function is called, 
but still, it is part of the parameter list declaration, not the body of 
the function.)

I have grave doubts that people will find this obvious, let alone 
useful. Having a function declaration, the parameter list, have 
side-effects outside of the function seems like both a surprising and a 
bad idea to me.


> It's well-defined - at least for positional args. Not sure what
> keyword arg handling would be though.

Why would it be any different? If it makes sense to allow:

def function(spam, eggs, something.foo)

assign to something.foo, then why should it matter whether it was called 
by keyword or positional? Or declared as keyword only?

def function(spam, eggs, *, something.cheese)


I don't think it makes sense either way, but it isn't because it is a 
keyword arg. I think it is arbitrarily mixing two distinct things into 
one convenient but confusing syntax.

function(spam=1, eggs=2, something.cheese=3)  # won't work



-- 
Steve
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to