I'm not a fan of `Tensor[T, ...]` because it has confusing semantics.
Tensors will usually be typed as:
```python class Tensor(Generic[DType, *Shape]): ... ```
where `Tensor[np.float64, Literal, Literal]` represents a 10x20 Tensor where each element has datatype `np.float64`. Let's say we want to represent a Tensor that has arbitrary shape.
+ `Tensor[np.float64, ...]` looks like it represents a Tensor of datatype np.float64 and arbitrary shape. But by analogy with the similar `Tuple[float, ...]`, it would have to represent any Tensor where all the *dimensions* are `np.float64`: `Tensor[np.float64, np.float64, np.float64]`, etc. That's not what we would expect for a Tensor.
+ To counter that, we might change the semantics of `Tensor[T, ...]`, to mean datatype T with arbitrary shape (i.e., `Tensor[T, Any, Any, Any]`, etc.), but that will be ambiguous for a class that has multiple unary generics like:
``` class Transformer(Generic[T_in, T_out, *Shape]): ...
# Is `T_out` int or Any? x: Transformer[int, ...] ```
New syntax like Transformer[int, str, ...] seems even more confusing.
+ The only remaining use afaik would be `Tensor[Any, ...]` to represent a Tensor where all parameters are Any. Given that `x: Tensor` already represents this, it doesn't feel worth adding fresh syntax to express the same.
In contrast, `Tensor[np.float64, *Tuple[Any, ...]]` expresses the fact that the datatype is `np.float64` but the shape can be anything. `Transformer[A, B, *Tuple[Any, ...]]` works for the other case. We can also state that the dimension types have to be int: `Tensor[np.float64, *Tuple[int, ...]]` to represent `Tensor[np.float64, int, int, int]`, etc.
I completely agree that the syntax is verbose and frankly not very pretty :) (TypeScript has a nicer `Tensor[float, ...any]` syntax.) That seems fine given that we don't really want to encourage this.
Overall, I see two options: + No explicit syntax for unbounded Tensors: We just have `x: Tensor` to support gradual typing as of PEP 646 and we can add unbounded Tensors in follow-up PEPs. Typecheckers would be free to treat `Float32Array = Array[np.float32, *Shape]; x: Float32Array` as `x: Array`, thereby making all parameters `Any`. This seems like the simplest option right now.
+ Explicit syntax where we substitute `Tuple[Any, ...]` for `Ts`: This would complicate an already heavy PEP, but would allow us to precisely express the fact that the shape can be anything.
On Sun, Feb 21, 2021 at 8:28 AM Eric Traut email@example.com wrote:
Hmm, I'm not a fan of `Tensor[*Tuple[Any, ...]`. That's really verbose and inconsistent with existing standards. And it would require all type checkers to add support for open-ended non-homogenous tyes, which would be a heavy lift. Let's save that for another future PEP.
I was proposing that we simply extend the PEP 484 tensor convention to all variadic generic types. So this would be `Tensor[Any, ...]`.
-- Eric Traut Contributor to Pyright & Pylance Microsoft Corp. _______________________________________________ Typing-sig mailing list -- firstname.lastname@example.org To unsubscribe send an email to email@example.com https://mail.python.org/mailman3/lists/typing-sig.python.org/ Member address: firstname.lastname@example.org