On Sun, Feb 14, 2021 at 9:36 AM Matthew Rahtz firstname.lastname@example.org wrote:
Hah, it just so happens I was skimming PEP 8 today and noticed the section on hobgoblins :)
Whether the same reasoning applies to tensor shapes I think depends on which parts of code we expect to get annotated with shapes first:
- Case 1: If we expect library code to get annotated with specific shapes
first, it'll break any old user code that tries to pass unparameterised tensors.
- Case 2: On the other hand, if we expect user code to get annotated
first, it'll be fine, because parameterised tensors can be passed to unparameterised library functions no problem.
Admittedly, I do think case 2 is much more likely, but would be keen to hear from others if I'm missing something here.
I'm not sure I agree with that. Library authors want to get fine details right (the efforts of the numpy folks show this desire) while users, once they have written code, would prefer it to never break, even if they upgrade to a newer version of the library. And they're willing to tweak the meaning of "break" to reach this nirvana. :-)
Also, though, if you're saying the rules for tuple were made that way deliberately, that updates me significantly towards thinking we should just respect those rules, advocating the use of a cast when otherwise necessary.
Those rules were made deliberately for tuples. I think a case can be made that the shape of a tensor is a different kind of animal. For one thing, a tuple of indeterminate length doesn't always mean something's incompletely typed. It could very well be one of the many use cases (some forced by the language or the stdlib) where tuples are used as immutable sequences. But I suspect that a tensor of unknown type always just means that the code was written before shapes were supported. And for those cases where a library function really does take a tensor of (almost) arbitrary shape, e.g. transpose(), maybe we should strive for a notation that is explicit about this, e.g. Tensor[..., X, Y] -> Tensor[..., Y. X].