On Thu, May 21, 2020 at 2:50 PM Alex Hall <[email protected]> wrote:

> Personally I think the best way forward on this would be to accept PEP
> 505. It wouldn't solve this particular problem in the most concise way but
> it would be pretty good and would be more broadly useful.
>

Having thought about this problem a bit more, I'm now less sure of this
stance. I think there's a decent benefit to being able to specify a
late/lazy default in the signature that goes beyond being concise, and I
don't think anyone has mentioned it.

Signatures are an important source of information beyond their obvious
essential need. They're essentially documentation - often the first bit of
documentation that human readers look at when looking up a function, and
often the only documentation that automated tools can use. And defaults are
an important part of that documentation.

Take a look at the official documentation for these callables and their
parameters which default to None:

https://docs.python.org/3/library/collections.html#collections.ChainMap.new_child
https://docs.python.org/3/library/logging.handlers.html#logging.StreamHandler
https://docs.python.org/3/library/json.html#json.dump (in particular the
`cls` parameter)

(we may not be able to change these signatures due to compatibility, but
they should still demonstrate the point)

In all cases it's not immediately clear what the actual default value is,
or even what kind of object is meant to be passed to that parameter. You
simply have to read through the documentation, which is quite verbose and
not that easy to skim through. That's not the fault of the documentation -
it could perhaps be improved, but it's not easy. It's just English (or any
human language) is not very efficient here. Imagine how much easier it
would be to mentally parse the documentation if the signatures were:

```
ChainMap.new_child(m={})
StreamHandler(stream=sys.stderr)
json.dump(..., cls=JSONEncoder, ...)
```

In the case of json.dump, I don't know why that isn't already the
signature, does anyone know? In the other cases there are good reasons
those can't be the actual signatures, so imagine instead the ideal syntax
for late binding. The point is that the signature now conveys the default
as well as the type of the parameter, and there's less need to read through
documentation. Conversely you can probably also write less documentation,
or remove some existing clutter in an upgrade.

There's a similar benefit if the author hasn't provided any documentation
at all - it's not nice to have to read through the source of a function
looking for `if m is None: m = {}`.

The signature and its defaults are also helpful when you're not looking at
documentation or source code at all. For example, PyCharm lets me press a
key combination to see the signature of the current function, highlighting
the parameter the caret is on. Here is what it looks like for `json.dumps`:

[image: Screen Shot 2020-05-22 at 21.32.21.png]

That's not very helpful! Here's the same for logging.StreamHandler:

[image: Screen Shot 2020-05-22 at 21.33.08.png]

That's sort of better, but mentally parsing `Optional[IO[str]]=...` might
just slow me down more than it helps.

PyCharm also uses defaults for rudimentary type checking. For example, if
you set `{}` as a default value, it assumes that parameter must be a dict,
and warns you if you enter something else:

[image: Screen Shot 2020-05-22 at 21.35.07.png]

Of course it also warns that the parameter has a mutable default, which
this proposal could solve.
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/6TGESU6AQSDFLIV2UBHAB4E2NVVREVPA/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to