> I just realized there's a situation where bare generic types are important: when evolving a codebase, making certain types that weren't generic before generic.
Yeah, this is exactly the situation that I imagine we'll be in with array types: hopefully (at least in my personal ideal world) we'd be able to persuade library authors to make the existing types like `tf.Tensor`, `np.ndarray` etc generic in shape.
> So I'm not in favor of saying that `Tensor` is the only legitimate way to specify "a `Tensor` whose type arguments can be anything". If we think that concept is needed, then we should support `Tensor[Any, ...]`.
The idea I had in mind worked the opposite way around: it's less that `Tensor` should be the only legitimate way of specifying arbitrary parameters, and more that arbitrary type parameters should be what `Tensor` means, in order to support gradual typing if `Tensor` becomes generic. For cases where the user wants to deliberately specify "a Tensor of any shape", I'm imagining they'd do something like:
Shape = TypeVarTuple('Shape')
def pointwise_multiply(x: Tensor[*Shape], y: Tensor[*Shape]) -> Tensor[*Shape]: ...
This would specify that `x` and `y` can be an arbitrary shape, but they should be the same shape, and that shape would also be the shape of the returned `Tensor`.
(If the user instead wanted to say that `x` and `y` could be arbitrary, different shapes, they would use different `TypeVarTuple` instances. This would, of course, potentially rely on the type-checker being ok with only a single usage of a `TypeVarTuple` in a function signature. From a quick skim of the analogous discussion about `TypeVar` in typing-sig a few months ago, I get the impression the jury is still out on whether that should be an error. But luckily, I think this use case is likely to be rare enough that we can ignore that issue for now. I can't think of any specific functions off the top of my head which would take arbitrary arrays of different shapes.)
> I consider it a bug in mypy that it accepts `Tensor[()]`.
Interesting - do you say this mainly on the basis that since it causes a runtime error, it should also be a type error? To me, it feels more intuitive that this shouldn't be an error, based on the argument that `Tensor` behaves like `Tensor[Any]`, and (without thinking about it too hard - i.e. not thinking about how the variance should work) `Tensor[Any]` seems like it should be compatible with `Tensor[()]`.
> Interestingly, mypy does emit an error if you try to pass other illegal values as a type argument (like `Tensor`).
I was surprised by this, so I did a bit more experimenting. Mypy does indeed error for me too on `Tensor`, but that was only because of the lack of `Literal`. The following two examples do type-check fine for me with Mypy:
x: Tensor[Literal] = Tensor()
x: Tensor[int] = Tensor()
Having said all that -
> I don't think we should promote the use of "bare" generic types — those with no type arguments. That's typically indicative of an error on the programmer's part. Pyright accepts them, but it flags it as an error when "strict" mode is enabled.
This makes a lot of sense to me and I definitely think that such a flag should continue to exist and be prominently advertised. With the case of `Tensor`, too, it would be super helpful to have the type-checker error with "Hey, you haven't specified what shape this `Tensor` should be!"