Damn, sorry it's only now I'm weighing in on all this - it's been a busy week.
Thanks for this excellent feedback, Eric - and also for teasing out some of the implications through an initial implementation! This is super helpful :)
**Breaking the PEP into three pieces**: this is a great idea, Pradeep. I'll try to get some drafts done in the next few days.
**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:
* 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.
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` * The potential for confusion to users about when to use `Ts` and when to use `*Ts`
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?
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?
**Implementation**: no, we haven't started on an implementation yet; we were waiting to hear back from the PEP 637 folks/I've been busy with other things.
Will respond to the other issues soon :)
On Sat, 23 Jan 2021 at 06:23, Eric Traut firstname.lastname@example.org wrote:
After some additional thinking — and in consideration of your responses, I have a few more thoughts to share.
I thought of a way that we could avoid all changes to the grammar and eliminate the need for `Unpack`. Assuming we remove support for packed usages of variadic type vars as I previously suggested, that would leave only unpacked usages. And if all usages are unpacked, there's no reason to require the expression `*T` or `Unpack[T]` as long as "T" is designated a variadic type var when it is defined. We could augment the existing TypeVar constructor to support a parameter called `variadic`. The only downside I see is that the use of the star makes it clear to the reader of the code that the type var is variadic, but I think we could accomplish this through a naming convention like `Ts` or `T_va`.
Here's how that would look:
T_va = TypeVar("T_va", variadic=True) class Array(Generic[T_va]): def __init__(self, *args: T_va) -> None: pass def linearize(self, value: Array[T_va]) -> Sequence[Union[T_va]]: pass
I like the simplicity of this. It's easy to read, easy to implement, provides backward compatibility with earlier parsers, and avoids the need to introduce an alternative form like `Unpack`.
Guido clarified that all classes that support variadic type parameters should support zero-length forms. That sounds reasonable to me.
Guido also said that unspecified-length (open-ended) variadics should be supported. I'm less convinced here. This creates complications for the type constraint solver. It also creates a bunch of tricky ambiguities for concatenation. I'll continue to play around with this in the implementation and let you know what I learn.
I like the idea of breaking this PEP into the three pieces as suggested. I could see us including some limited forms of concatenation in phase 1. In particular, we could support type argument lists that contain at most one variadic type var where the variadic type var is the last element. For example, `Tuple[int, T_va]` would be allowed but `Tuple[T_va, int]` and `Tuple[S_va, T_va]` would be errors. This would allow for removal of prefixes and basic concatenation use cases, and I think it would be relatively straightforward to implement. Support for suffixes is much tougher. And I'm not yet convinced that support for multiple variadic type vars is even theoretically possible in the general case.
-- Eric Traut Contributor to pyright and pylance Microsoft Corp. _______________________________________________ Typing-sig mailing list -- email@example.com To unsubscribe send an email to firstname.lastname@example.org https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: email@example.com