On Sat, Jan 08, 2022 at 08:36:57PM -0600, Skip Montanaro wrote:
So if you hate type annotations because they are unreadable, then you hate Python because Python is unreadable.
That seems rather harsh. I suspect if those of us who are uncomfortable with the typing subsystem actually hated Python we would have found our way to the exits long ago.
Right. That's my point, or at least part of it. I've read heaps of complicated, confusing, even outright obfuscated Python expressions. Some of it even written by me, that a couple of months later I couldn't work out what I had done. So did I conclude that "Python expressions are unreadable"? No I did not. When I read an obfuscated, confusing, complex type hint, do I decide that all type hints are "unreadable"? No I don't do that either. Here is the type hint for `len`, taken from the stub file in typeshed: def len(__obj: Sized) -> int: ... Putting the mysterious double underscore naming convention aside, I do not find it credible that anyone capable of programming Python beyond a beginner level can find that "unreadable". Not by any definition of unreadable I can think of. Even if you can't guess what "Sized" means, it isn't that hard to track it down: from typing import Sized # among many others and from there to collections.abc. This is not brain surgery folks :-) https://www.youtube.com/watch?v=THNPmhBl-8I We should not dismiss all of typing as "unreadable". Type hints are just expressions. If you can read Python expressions, you can read type hints. Some are simple, some are complex, some are confusing. We should do our best to improve the complex and confusing ones, using all the tools at our disposal: * named type aliases; * style guides for laying out the annotations to make them physically easier to read (one parameter per line in complex function signatures works for me); * improving the `typing` module DSL; * perhaps even adding new syntax like the arrow syntax; but we shouldn't dismiss the whole thing as "unreadable" if what we actually mean is "its unfamiliar and I don't like it".
Typing was always supposed to be optional,
And it still is. Alas, we can't do anything about third-party projects mandating type hints (maybe they have a good reason for mandating them!). But perhaps we can help discourage some of the excessive zeal for annotating everything in sight.
so I didn't worry too much about it at the time. As Jack indicated though, while it may be optional at the language level, it's often not truly optional at the organizational level.
We can't prevent organisations and third-parties mandating the use of linters, or IDEs, or particular naming conventions, or any other style convention they want. PEP 8 zealotry is especially prevalent out in the world. I've come across people with their own idiosyncratic style, like "Never use comprehensions, only for-loops", and others who insist "Never use for-loops, only comprehensions". What are we going to do, dismiss comprehensions as a bad idea because some people are irrationally pro- or anti-comprehensions? I don't think so.
As you indicated, there are two things going on, Python syntax and the semantics which go along with it. Python's economical syntax is a terrific reflection of its runtime semantics, hence the use of the phrase "executable pseudocode" to describe Python (at least in the past).
Right. Beyond the easy cases, typing is hard. It is often easier to write code that works for typical data you care about, than to convince the type-checker that the code works :-) I don't know if this applies to gradual typing, but I imagine it probably does. Type checking is a hard problem, and if your type system is powerful enough to use, it is undecidable: http://composition.al/blog/2017/02/27/why-does-a-turing-complete-type-system... https://forums.swift.org/t/swift-type-checking-is-undecidable/39024 Even if your type system is not Turing complete, it is still going to be pretty powerful. We're not using Pascal any more :-) And that means that the types themselves are communicating some fairly complex semantics. Blaming the syntax for something which is inherently hard is not helpful.
Just because you are using Python syntax for your declarations doesn't mean that (a) mapping the semantics of the desired declarations onto existing syntax will be straightforward or (b) that the semantics of those declarations will be reflected as effortlessly as it reflects runtime semantics.
Indeed. And we can say the same thing about using Python syntax as code. Mapping the semantics of your desired behaviour into syntax is not always straightforward, nor is reading the code and inferring the semantics. If it were, anyone could be a rockstar ninja coder, and programming would be a minimum wage job. We accept without blinking comprehensions, decorators, descriptors, metaclasses, multiple inheritence, horrifically complex class hierarchies, abstraction on top of abstraction, design patterns, metaprogramming, threading, async programming and more, all of which can at times be every bit as complex as typing. I've even had the pleasure of trying to understand Continuation Passing Style in Python. The code clearly worked, but I'm damned if I could understand how. As programmers, there is a ton of complicated stuff we have to deal with. So why the hate towards type hints? -- Steve