On Thu, May 21, 2020 at 02:50:00PM +0200, Alex Hall wrote:
> On Thu, May 21, 2020 at 12:27 AM James Lu <jam...@gmail.com> wrote:
> 
> > > This is already valid in 3.8, so we should forget about overloading :=
> > > with a second meaning.
> >
> > def func(x=(a:=expression), y=a+1):
> > def func(x:=options):
> >
> > These two syntaxes do not conflict with each other.
> >
> 
> Technically no, but there is potential to confuse beginners.

Forget beginners, I know that will confuse me!

Technically, *yes*, they do conflict.

Ask yourself what the walrus operator `:=` means in Python 3.8, and you 
have a single answer:

- "it's like `=` only it works as an operator".

Now ask yourself what the walrus operator means if James' proposal is 
accepted. The answer becomes:

- "well, that depends on where you see it..."

or:

- "in this context, it's like `=` only it works as an operator"

- "but in this context, it changes the meaning of assignment 
  completely to something very different to how the `=` works 
  everywhere else"

That's certainly a conflict.

This isn't necessarily a deadly objection. For example, the `@` symbol 
in decorator syntax and the `@` symbol in expressions likewise 
conflicts:

    @decorate(spam @ eggs)
    def aardvark(): ...

but both uses of the `@` symbol well and truly proved their usefulness. 
Whereas in this case:

- the walrus operator is still new and controversial;
- James' proposed `:=` in signatures hasn't proven it's usefulness.


>  What about:
> 
>     def func(x=:options):

As a beginner, it took me months to remember to use colons in dict 
displays instead of equals signs, and they are two extremely common 
operations that beginners learn from practically Day 1. Even now, 20 
years later, I still occasionally make that error. (Especially if I'm 
coding late at night.)

You're proposing to take one uncommon operator, `:=`, and flip the order 
of the symbols to `=:`, as a beginner-friendly way to avoid confusion.

As if people don't get confused enough by similar looking and sounding 
things that differ only in slight order. To steal shamelessly from the 
stand-up comedian Brian Regan:


    I before E except after C,
    or when sounding like A like in NEIGHBOUR and WEIGH,
    on weekends and holidays,
    and all throughout May,
    you'll be wrong no matter what you say.


> or a more realistic example:
> 
>     def func(options=:{}):


Add annotations and walrus operator:

    def flummox(options:dict=:(a:={x: None})):

and we now have *five* distinct meanings for a colon in one line.


> Personally I think the best way forward on this would be to accept PEP 505.

For the benefit of those reading this who haven't memorised all 
multiple-hundreds of PEPs by ID, that's the proposal to add None-aware 
operators to the language so we can change code like:

    if arg is None:
        arg = expression

into

    arg ??= expression


In this thread, there has been hardly any mention of the times where 
None is a legitimate value for the argument, and so the sentinal needs 
to be something else. I have written this many times:

    _MISSING = object()

    def func(arg=_MISSING):
        if arg is _MISSING:
            arg = expression

Null-coalescing operators will help in only a subset of cases where we 
want late-binding of default arguments.


-- 
Steven
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/3NOYNP3SSFQ7APYMQ3EJX2XWJMXHX5CE/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to