
My question (which you didn't answer) is which variant should we recommend, and why? I honestly find both `(bytes | str)?` and `bytes? | str?` unpleasant to look at, and the fact that it's not clear which is better makes it even worse. We could even recommend `bytes | str?` but that's even weirder.
Yes, I agree that all `|` variants with `?` do not look too pleasant. And that multiple possibilities to write the same things make it even worse. Here I want to show some examples from other languages that already have this feature. TypeScript. It has both `null` and `undefined`. So, there are two syntax constructs to represent it: `| null` and `?` respectively. There's a setting to change this a bit, but let's omit it for now. We are going to use the `--strict` version. function worksWithOptional(param?: number) {} worksWithOptional(1) worksWithOptional(undefined) function worksWithNullable(param: number | null) {} worksWithNullable(1) worksWithNullable(null) function worksWithUnion(param: number | string) {} function worksWithOptionalUnion(param?: number | string) {} function worksWithNullableUnion(param: number | string | null) {} It is clear why TypeScript has both `?` and `| null`, because in JS there are two "empty" states. But, it is also important to highlight that TypeScript does not have this `str? | bytes` vs `(str | bytes)?` problem. It either has a single `?` near the argument / property definition, or union with explicit `null` Flow is a bit different. It allows both `null` and `undefined` to be under `?` when placed in type definition. And also has `?` near arguments / props to mark them to work with `undefined`, but not `null`. See https://stackoverflow.com/questions/50112490/what-is-the-difference-between-... /* @flow */ function foo(x: ?number | string) {} foo(undefined) foo(null) foo(1) function bar(x: ?(number | string)) {} bar(undefined) bar(null) bar(1) function baz(x: number | ?string) {} baz(undefined) baz(null) baz(1) function withOptional(x?: number) {} withOptional(1) withOptional(undefined) It looks way less readable compared to TS. Scala (which is mentioned in the original PEP) (dotty) has only a single way of doing it: `Int|String|Null` https://dotty.epfl.ch/docs/reference/other-new-features/explicit-nulls.html Currently it is in development and things may change. It has no special syntax for `Null`. Scala usually uses the `Maybe` monad to handle empty states, so there's no need for a special syntax. Other languages either don't have `?` syntax (like Scala and Julia), or have different `Null` concepts (like Rust and Haskell), or have different Union concepts (like Swift, Kotlin and Rust), or go really wild in terms of syntax like `T.nilable(T.any(Number | String))` in Ruby or `float() | none()` in Elixir. So, there is nowhere to copy any alternative solutions from. At least in the mainstream languages. My personal opinion: 1. This looks great, way better than now with `Optional`: `def some(arg: str? = None): ...` compare it with ``` from typing import Optional def some(arg: Optional[str] = None): ... ``` 2. This looks a bit less great: `def other(arg: str | None = None): ...` But still pretty pleasant 3. The union solution (2) does scale. It can easily become `str | bytes | None` 4. The `?` (1) solution does not scale well, as I have shown above, `str?` has trouble becoming `str? | bytes` or `(str | bytes)?` (I even don't mention other possible types operators like `&` for intersections that can be added later) чт, 10 сент. 2020 г. в 03:08, Guido van Rossum <guido@python.org>:
The requirement of having a PEP sponsor is to make sure that poorly thought-out proposals are stopped with minimal waste of resources. Your proposal, even though I am not particularly in favor of it, deserves to be a discussion to have. (For example, it seems that TypeScript is surviving even though it also has this problem of how best to write `Optional[Union[...]]`.)
So if you can't find someone else to sponsor it, I will, even though when it comes down to accepting it I would probably recommend that the SC reject it. Even that would be useful, since then we can point to the rejected PEP when the idea is brought up again. :-)
Finally -- wouldn't we need to have a new dunder method/protocol so the operator can be overloaded for other functionality?
On Wed, Sep 9, 2020 at 3:12 PM Maggie Moss <maggiemoss@fb.com> wrote:
Thanks for the feedback.
One additional question here: Would anyone like to sponsor this PEP?
Thanks, Maggie ------------------------------ *From:* Guido van Rossum <guido@python.org> *Sent:* Thursday, September 3, 2020 3:18 PM *To:* Maggie Moss <maggiemoss@fb.com> *Cc:* typing-sig@python.org <typing-sig@python.org> *Subject:* Re: [Typing-sig] Update: Work on Optional Syntax PEP
Wow, you've been busy! (I know I still owe you a review on the PEP 604 implementation. It's on my TODO list. :-)
My main observation at this point is that introducing a new token means that there is no way to use this in code that has to be backwards compatible with Python 3.9 and before (assuming you could get it into 3.10). This is different for PEP 604's `|` operator, which can be used in Python 3.7+ as long as the `from __future__ import annotations` magic import is used to avoid runtime errors on things like `int | str`. The `|` operator could also be used in typeshed, since it is valid Python 3.7 syntax. (While I don't know of any type checkers that currently support it yet, supporting it would not require changes to the Python *parser* -- at least typed_ast can handle it without changes.)
However, this shouldn't be a big strike against the proposal. In a few short years Python 3.10 will be the oldest version supported and all will be well.
Another concern I have is that we already have two ways to spell "optional": `Optional[T]` and `T | None`.
Finally, IMO the argument against `Optional[T]` is stronger than the argument against `T | None`. (But your point that 7% of annotations use Optional is well taken.)
--Guido
On Thu, Sep 3, 2020 at 12:04 PM None via Typing-sig < typing-sig@python.org> wrote:
Hi there,
Recently I have been working on an implementation for PEP 604 ( https://www.python.org/dev/peps/pep-0604/ <https://urldefense.proofpoint.com/v2/url?u=https-3A__www.python.org_dev_peps_pep-2D0604_&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=f28uZNOWonDFk7FJQDoV1HxAt9325GELs0nSw_fZ-QQ&m=0jLG3fTmrb4AQ6ZhABOSg26ax9ZdSRYxgUFXFZj2kyg&s=J96mesCJIlD6NfDAAsXL0dFJXR920_vBYasEq8Zgn6A&e=>). While working on this, I started reviewing and exploring what new Optional syntax would look like in the Python language.
I've written a rough draft of a PEP and wanted to present it to this email list before submitting a PR. I know this is a topic that has been discussed in many settings (Github issues, in person typing meetups, etc. )previously, and wanted to solicit feedback here first. Let me know if submitting a PR would be a better way to gauge sentiment and feedback on this proposal.
Draft Proposal (branch compare): https://github.com/python/peps/compare/master...MaggieMoss:optional-syntax-p... Gist: https://gist.github.com/MaggieMoss/c848cb3a581979f445d075c15629c950
Thanks again, Maggie _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ <https://urldefense.proofpoint.com/v2/url?u=https-3A__mail.python.org_mailman3_lists_typing-2Dsig.python.org_&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=f28uZNOWonDFk7FJQDoV1HxAt9325GELs0nSw_fZ-QQ&m=0jLG3fTmrb4AQ6ZhABOSg26ax9ZdSRYxgUFXFZj2kyg&s=ZeTEN7ql-2_nV4tE3l7PRyEUj6YjwgYR2QlFR3F9QRs&e=> Member address: guido@python.org
-- --Guido van Rossum (python.org/~guido <https://urldefense.proofpoint.com/v2/url?u=http-3A__python.org_-7Eguido&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=f28uZNOWonDFk7FJQDoV1HxAt9325GELs0nSw_fZ-QQ&m=0jLG3fTmrb4AQ6ZhABOSg26ax9ZdSRYxgUFXFZj2kyg&s=WzHjojUuk8ytY-7ARrq2LELrpwxQNeOsZCaQ867H_Sk&e=> ) *Pronouns: he/him **(why is my pronoun here?)* <https://urldefense.proofpoint.com/v2/url?u=http-3A__feministing.com_2015_02_03_how-2Dusing-2Dthey-2Das-2Da-2Dsingular-2Dpronoun-2Dcan-2Dchange-2Dthe-2Dworld_&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=f28uZNOWonDFk7FJQDoV1HxAt9325GELs0nSw_fZ-QQ&m=0jLG3fTmrb4AQ6ZhABOSg26ax9ZdSRYxgUFXFZj2kyg&s=1RqmKCAxL8BNbxJclFdhkTeLb0_yNHHeJBmQLFM3-oQ&e=>
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...> _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: n.a.sobolev@gmail.com