What happened is I started losing out on the advantages that Python provides as a dynamically-typed language without truly gaining those of statically-typed ones. Then I realized, type hints are just that: hints. They're a form of documentation. In some cases, they're very helpful, but in other cases, it doesn't really make sense to use them. I don't need to appease mypy. The type hints are their for the benefit of myself and other developers.
Probably just used to writing poor quality (immediately unintelligible to someone other than the author but functional) code then.
(Similar to when you something you wrote is hard to test, it’s probably just poorly abstracted code.)
One example is that variable re-assignment can cause type errors in mypy but re-assigning a variable to a value of a different type is an extremely common and reasonable thing to do in Python. Another situation where strict typing can be borderline hopeless is when parsing e.g. very dynamic content like json. Sure you could encode every possible situation using types but this would basically defeat the purpose of using Python for such a task.
I mean, machines serve people (for now!). So in addition to type documentation, type annotations are useful for things like "jump to definition" and "find references" and automatic refactoring. Moreover, the utility of annotations for type documentation depends on the correctness of those type annotations--if you don't have something like Mypy, then those inevitably annotations grow outdated over time and incorrect type annotations are even worse than none at all.
> tools like pytype or mypy will never capture all the complicated hacks possible in the Python type system
Technically you can represent any complicated hack if only via `any`, but that's just pedantry and we all know what you mean. Even still, it's not like "well you can't represent everything, so there's no point in trying to appease mypy" (which may not be your intended implication--I can't tell). The benefits of appeasing mypy are proportional to the amount of your code that is properly annotated--this is the thesis of gradual typing.
> as evidenced by only 15% of repos passing mypy
This very likely indicates that 85% of repos aren't running mypy regularly, or they're in some transition state. Certainly more than 15% of real-world Python can be described via Python type annotations.
> as evidenced by only 15% of repos passing mypy
That is no evidence. Of course, if you don't have mypy in CI (or pre-commit hooks or whatever), your repo will not pass mypy. But if you have it in CI, then you can rely on them being correct.
> tools like pytype or mypy will never capture all the complicated hacks possible
But they can either enforce everything being correctly typed (if you go to really strict settings), or yes, you will have some code untyped, so you will be careful around that part. It's not like all or nothing.
That's often a mistake even in typed languages like typescript. Satisfying a static type analyzer isn't enough. Real data is whatever it is going to be. If your types are meaningless at runtime, you can easily encounter type mismatches.
Static typing as implemented in typescript and python type hints is a tool for engineers instead of a tool for systems.
foo=PydanticFoo(**request.json())
Will try and validate a json request against the implied schema provided by the type hints on PydanticFoo while constructing it and will throw if it fails.Pydantic is amazing!
Compare it to Typescript which is a similar sort of tacked on type hinting system - Typescript is basically always machine checked.
But it's a wart worth the conciseness, at least, until a better idea comes along.
Maybe if type hints could be optionally enforced as a language feature, I'd feel it was more integrated.
In practice, most modern statically typed languages maintain soundness through a combination of compile time and runtime checking.
Rust, C, C++ - all do not keep around this information.
You're right that the JVM languages (and thus, naturally, C#) do it differently. I think it is a bit silly to name out each of the JVM languages separately.
I think basically every managed statically typed language ends up carrying around runtime representation and uses some amount of runtime checks.
AFAIK - and this might be either dated or just wrong - the two places GHC doesn't fully erase are 1) polymorphic recursion (where if we squint it's probably not unreasonable to treat the dictionaries as type tags), and 2) when the programmer explicitly asks for run-time type information with Typeable.
However, such matches are considered valid code: "non-exhaustive match" is a warning by default, even if most people advise to turn that warning into an error.
In other words, the `Match_failure` exception is part of OCaml non-typed semantics and there is no soundness issue involved here.
For instance
let f x = match x with
| [] -> ()
is translated into (is_empty/267 =
(function x/269 : int
(if x/269
(raise (makeblock 0 (global Match_failure/18!) [0: "r.ml" 1 17]))
1)))
where you can see the exception being build and raised in the `then` branch of the test.
Contrarily, the total function let is_empty x = match x with
| [] -> true
| _ :: _ -> false
becomes (let (is_empty/267 = (function x/269 : int (if x/269 0 1)))
And since the function doesn't need to handle the failure case, it doesn't have that `(raise ...)` case.Another important point is that type system information is only needed to check the exhautiveness of pattern matching in presence of GADTs. Otherwise the exhautiveness of pattern matching can be checked using syntatic criteria on the pattern matching and type definitions.
In the GADTs case, the type system is only used to remove the failure branch. For instance,
type 'a t = A: int t | B: float t
let always_a (x:int t) = match x with
| A -> ()
| _ -> .
is translated to (let (always_a/270 = (function x/272[int] : int 0))
because the typechecker can prove that the `B` case is impossible.
In other words, GADTs are yet another instance where the type system can be used to eliminate dead code in the untyped IR.Makes sense to me.