Finally set up neovim with pyright; use types on every single fucking thing, and now I love Python[1].
Can't wait to see TC39 become a reality (learned about it just this past week on HN, actually). Maybe I'll enjoy Javascript too.
--------------------
[1] Within reason; the packaging experience is still extremely poor!
Besides, you see to be confusing Python run-time with Python typecheck-time, theoretically unfortunate, but again practically irrelevant distinction. (Unfortunate since Python typecheck is basically a different language than Python execution; irrelevant, because the right subsets of both align well.)
When you're at a level of theory where terms like "type constructor" are natural, it's unreasonable to expect any of it to be applicable to Python. This is why the Haskell people speak of dynamically-typed languages in the Python mold as "untyped" regardless of their attitude towards implicit casts.
And I love it, and have been using it for decades, and write beautiful things where the annotations hardly ever seem worth the effort — perhaps for documentation, but not for a static checker. Then I look at other, newer Pythonistas trying to figure out how to write complex generic type expressions (and sacrificing backwards compatibility as they keep up with the churn of Python figuring out how to offer useful annotation syntax) and deal with covariance vs contravariance etc. and I just smile.
If the type was a type, you'd not be able to use it as a value.
As a trivial example, if I create a type alias from “string” to “foobarId,” I now (assuming a compliant language) can prevent code that consumes foobarIds from accidentally consuming a string.
You can run a third party linter on those comments, but you must hope that they're correct. There are usually some checks for that, but they're only reliable in trivial cases.
This is not static typing any more than "you can use emscripten to transpile JavaScript to C" means that JavaScript is a low level language with native assembly support. It's a huge step forward from "no system at all" and I'm thrilled it exists, but it's hardly the same thing.
def f(a: "something like an int", b: "another int-like thing"): pass
def g(a: sys.stdin, b: sys.stderr): passErlang and Clojure were the early ones, TypeScript followed, and now Python, Ruby, and even Perl have ways to specify types and type check your programs.
"Optional typing" is not the same as "Static typing".
Great, my program will crash, because I forgot to opt-in to typing :-/
And? Void pointers are not the default type :-/
With Python I have to do extra work to get type errors.
With C I have to do extra work to hide the type errors.
I am battling to understand the point you are making.
You have to do extra work to type it.
I’m not aware of any other statically typed language that does that.
Hopefully that helps you in your battle.
> You have to do extra work to type it.
Nope. Casting the return from `malloc` is a code-smell in C. You have to do extra work if you use `malloc` in C++.
> Hopefully that helps you in your battle.
Not sure what you mean by this - weren't you the one who dragged C into a conversation about Python?
C is statically typed, but weakly typed - you need to throw away types to do a bunch of run of the mill things. Python is dynamically typed, but strongly typed, where it will just fail if typed don't resolve.
C# and C++ are both statically typed and strongly typed, although C# more than C++ in practice.
Start using properties and it is in the thousands.
Most code should be typed. Python is great for prototypes, but once the prototype gels, you need types.