On Sat, Jan 23, 2021 at 5:52 AM Matthew Rahtz <mrahtz@google.com> wrote:
**Whether to support both packed and unpacked versions**: funnily enough, supporting only the unpacked version (in the form `Tuple[Ts]`) is what we initially started with. I had to do some digging in the doc history to figure out why we decided to switch. I think what happened was:

Looks like we have come full circle here. :-)
* Someone suggested renaming `Map` to something different to avoid confusion with `typing.Mapping`
* At some point during the discussion, without realising it, I got confused about the difference between the concept of `Map` (`Map[List, Ts] -> Tuple[List[T1], List[T2], ...]`) and the concept of connecting generic classes to variadic type variables (this isn't what we were calling it even back then, but for illustration: `UnpackInto[Ts, Tuple] -> Tuple[T1, T2, ...]`
* As a result, we renamed `Map` to `Apply` 😱
* But then after I'd read about variadics in Typed Scheme and what `apply` means in Typed Scheme  (and also what `apply` did in old versions of Python), I realised that calling `Map` `Apply` made no sense, and renamed it back to `Map`, and introduced `Expand` for the other concept: `Tuple[Expand[Ts]]`.
* Then Lucio pointed out that `Expand` was super verbose and that using a star would be cleaner, which made a lot of sense.

I never followed the Typed Scheme thing. But I've been learning about the corresponding functionality in TypeScript, and it uses `...X`, here which is JavaScript's and TypeScript's spelling of `*X` in various places. I also find it the `*` useful hint for the user: When I see `Tuple[*X]` I immediately know that the length of the tuple is variadic. If I were to see `Tuple[Ts]` I'd have to remember that the naming convention tells me that the tuple is variadic. Readability Counts.
Thus, complexity was born.


To be fair, I also liked the star thing for two reasons:

* It helped to visually differentiate variadic type variables from regular type variables (though Eric, I agree that suffixing with e.g. `_va` or `s` is an easier way to do this)
* It strongly reinforces the idea that a variadic type variable on its own behaves like a `Tuple` - which I liked because then it was intuitive was a variadic type variable on its own 'was' (that is, if `Ts` on its own meant the unpacked version, then a variadic type variable was sort of a free-floating list of types that I didn't have a pre-existing mental concept for, and that seemed confusing to me)

The latter still seems compelling to me - but the counter-arguments are admittedly also significant:

* The complications of i) a grammar change and ii) the introduction of `Unpack`

I think the grammar change is for the best. It values explicitness over magic. `Unpack` is temporary, only needed for backwards compatibility.
* The potential for confusion to users about when to use `Ts` and when to use `*Ts`

If you think about Ts as a sequence it should be clear -- when doing computations with values, users know when to use f(*args) vs. f(args).
As much as it pains me to kill my darling, I find myself leaning towards agreeing that maybe it would be better if we dropped the star idea. Thanks for being willing to disagree, Eric, and potentially break us out of a rut here!

I still reserve the right to change my mind once I've tried making the corresponding changes to the PEP, though. Two potential blockers that come to mind straight away are:

1. What should the type of `*args` be?

We could just go back to `*args: Ts`, with a special rule that if `*args` is annotated as being a variadic type variable then the usual rule doesn't apply. Guido, how would you feel about that?

No matter what we do, `*args` needs to be some kind of special case (because PEP 484 screwed up here).
2. What if a function wants to return just the types in the variadic type variable?

Actually, I'm happy to just do `-> Tuple[Ts]`. Does anyone else have a problem with this?

And with the star, we could require writing `-> Tuple[*Ts]`. (Again, EIBTI.)

--Guido van Rossum (python.org/~guido)