On Mon, Apr 20, 2020 at 10:46 PM Christopher Barker <pythonchb@gmail.com> wrote:
On Mon, Apr 20, 2020 at 1:35 PM Alex Hall <alex.mojaki@gmail.com> wrote:

So let's assume that a beginner is likely to notice arguments out of order and think that something is wrong, and focus on what happens from there. I think it's fair to say that the main concern is that they will have to look up and learn the syntax, and that is significant.

As far as beginners are concerned, yes, it's one more thing to learn of a already complex interface. But that's not my larger concen: I'm found that newbies often get confused about scope -- that "x" when you call a function is different than "x" in side that function, even though they may sometimes be the same name (same value).

And if we make it even easier, and more common, to implicitly use the same names, they will only be more confused.

Python has become much less of a newbie friendly language over the years, and that's fine, but I'd like it to be considered.

-CHB


This and another post about the complexity of function call syntax has convinced me that it's not worth adding more features to function calls. Let's only consider dicts.

Unfortunately the most common use case is still functions and keyword arguments, which means immediately unpacking a dict. I was playing around with refactoring this call into the new syntax:

```
    return _copytree(
        entries=entries,
        src=src,
        dst=dst,
        symlinks=symlinks,
        ignore=ignore,
        copy_function=copy_function,
        ignore_dangling_symlinks=ignore_dangling_symlinks,
        dirs_exist_ok=dirs_exist_ok,
    )
```

Here it is with the function call syntax which sadly I don't want anymore, even though it looks so pretty:

```
    return _copytree(
        **,
        entries,
        src,
        dst,
        symlinks,
        ignore,
        copy_function,
        ignore_dangling_symlinks,
        dirs_exist_ok,
    )
```

Here it is with the dict syntax I've been advocating for:

```
    return _copytree(**{**,
        entries,
        src,
        dst,
        symlinks,
        ignore,
        copy_function,
        ignore_dangling_symlinks,
        dirs_exist_ok,
    })
```

A couple of things strike me about this:

  1. `(**{**,` is an ugly, complicated sequence of punctuation.
  2. It's really not obvious what the best way to format this is. I hate trying to decide between squeezing too much into one line and using too many lines.
  3. It's probably quite easy to forget the comma after the `**` and thus accidentally unpack the `entries` value. It'd be like accidental implicit string concatenation. We would probably need to make doing that a SyntaxWarning or SyntaxError, and ensure that there's a helpful message that makes it easy to find the problem.

We can deal with (3) by using a different separator, e.g. `:`, `::`, or `=`. But that still leaves (1) and (2). And it means we don't get to just switch on the mode with a normal `**kwargs`.

Another possibility I'm considering is to not have any kind of syntax that exists only for this purpose. The rule could be simply "a lone name in a dict is an auto-named pair". It just needs to be clear that you're using a dict and not a set, so there needs to be at least one colon or `**` present. Then the call would look like:

```
    return _copytree(**{
        "entries": entries,
        src,
        dst,
        symlinks,
        ignore,
        copy_function,
        ignore_dangling_symlinks,
        dirs_exist_ok,
    })
```

That looks pretty weird, right? At the same time it sort of feels like after the first pair it's saying "and so on and so forth, you get the idea".

One thought I have about this, which also somewhat applies to any of the mode-switch syntaxes for dicts, is that it's quite easy to accidentally transform a dict into a set if part of the dict gets deleted. Not sure how much of a concern that is.