Hello all,
There's some overlap between PEP 612 and PEP 646 and I thought it would be
good to start a discussion. Sorry if this has already been covered, just
trying to catch up! :-)
The current draft of PEP 646 includes this example:
```
Ts = TypeVarTuple('Ts')
def f(func: Callable[[int, *Ts], Any]) -> Tuple[*Ts]: ...
def foo(int, str, float): ...
def bar(str, int, float): ...
f(foo) # Valid; inferred type is Tuple[str, float]
f(bar) # Not valid
```
This is similar to the Concatenate operator PEP 612 introduces. Compare:
```
P = ParamSpec('P')
def f1(func: Callable[Concatenate[int, P], Any]) -> Callable[P, Any]: ...
Ts = TypeVarTuple('Ts')
def f2(func: Callable[[int, *Ts], Any]) -> Callable[[*Ts], Any]: ...
```
Question 1: Do f1 and f2 differ?
I'm assuming f2 won't preserve keyword arguments like ParamSpec does and
that a function that takes keyword-only arguments would be invalid if
matched against a TypeVarTuple. But some language in the PEP mentioning
that would be good.
Question 2: Should ParamSpec support splatting? Should Concatenate exist at
all?
That is, in addition to (or instead of) `Callable[Concatenate[int, P],
Any]` we spell it `Callable[[int, *P], Any]`. There shouldn't be any
parsing / runtime concerns for ParamSpec splatting, since it would just be
normal sequence unpacking. If Concatenate is destined to be vestigial, it's
not too late to get rid of it! :-)
If Concatenate should exist, should `Concatenate[x, Ts]` generally be a
synonym for `[x, *Ts]`?
Note that Concatenate can't serve as a replacement for PEP 646's proposed
Unpack, since you can't spell `def f(*args: Unpack[Ts])` and stuff like
`[int, *Ts, float]` becomes awkward. (But as far as I can tell, Unpack /
splatting could do everything Concatenate would).
Thanks,
Shantanu