1) Not type checking at runtime is exactly what people mean by static typing, because the definition of static typing means the checks are done before execution.
2) This does not make it harder to optimize, on the contrary if they generated type assertions it would considerable slow things down on the boundary of typed and untyped code.
3) C++, Go, Rust, Haskell they are fully statically typed, the only difference is they support varying levels type-inference which means you don't need to "type out the type" but it's really orthogonal to the whole optional/static/dynamic typing issue.
"Type inference refers to the automatic deduction of the data type of an expression in a programming language."
https://en.wikipedia.org/wiki/Type_inference
Which you'll notice C++ and Go, are listed as languages with type inference.
But you're right that they don't have as nearly as strong type inference as rust, which doesn't have as strong as haskell etc.
Depending on how simple "deduction" can be, that arguably includes every language that includes expressions.
And if the deduction is required to include usage information, it quite arguably excludes C++/Go style "var": a variable declaration is not an expression.
Generally, that Wikipedia article doesn't seem very good - check the talk page.
(When you have a real type inference engine, you spend a lot of time trying to figure out what it did, or why it didn't do something.)
That being said, I have never encountered a program that was hard to understand because types were inferred rather than explicitly annotated. I use explicit type annotations in two situations:
(0) As a compile-time analogue of printf debugging. Not exactly a joyous thing.
(1) At module boundaries, to control what modules expose to each other.
Perhaps the parent was trying to talk about "HM type inference" or something, but "type deduction" is also a fine name for a subset of type-inference, and perhaps more explicit for C++ and Go.
(0) Generating a system of type equations, by recursively scanning the AST.
(1) Solving the system of equations. The nontrivial nature of this step is what makes type inference, well, inference.
In Go and C++'s case, the generated type equations come out already solved (that is, of the form `TypeVar = TypeExpr`), so there's nothing to infer!
Mypy is not about optimising anything, it's about static correctness guarantees. If you're developing PyPy, type hints shouldn't be making your life any better or worse.
Lastly, the 'direction' you describe that everyone else seems to be taking, is the exact same direction mypy has taken. Type annotations are only required at the method/function level.
My_dict: defaultdict[int, List[int]] = defaultdict(int)I've run into that with functions that take NumPy arrays. You can pass a Python array, but "+" behaves very differently. For a NumPy array, it's element by element addition. For a Python array, it's concatenation. You want to catch that.
Or perhaps, he realizes that to require these typechecks at runtime would either
- require a massive rewrite of the CPython interpreter
- cause a performance penalty in code that is statically typed (there are pure python libraries that allow this, and yes your code runs slower)
Further, it offers a relatively narrow amount of help to pypy, which has already come out and said that they have no interest in using annotations for efficiency gains, because they're a jit and they don't need them.
Von Rossum on PyPy (2016): "Otherwise, there are specialized versions of Python like PyPy that are still around."
[1] https://bitbucket.org/pypy/pypy/src/default/rpython/translat...
I think that's a fair trade off, and easily doable. Those who want it and respect it get the speedup, those who don't don't lose anything.
If you have to double check types at runtime, you've already lost.
Now if it isn't correct, you'll probably get a segfault or some nasty error and it'll blow up.
If you take that seriously, compilers can't use type information to optimize. It feels like Von Rossum is making life hard for the PyPy compiler project again. If they had hard type information, they could do serious optimizations. Guido's CPython still uses a CObject for everything internally, so it doesn't benefit much from this.
The direction that everybody else seems to be taking is that function parameters, structure fields, and globals are typed, but local types are inferred as much as possible. C++ (with "auto"), Go, and Rust all take that route. Type information on function parameters and structure fields is an important item of documentation; if the language doesn't support that, you need to put it in separate documentation or comments. But writing elaborate type declarations for local variables is no fun, and the compiler can usually infer that info anyway.