Live data from Hacker News

A Failed Experiment with Python Type Annotations

mortoray.com

31–40 of 82 posts

Re: A Failed Experiment with Python Type Annotations

#31
post #13

Earlier quoted context omitted.

> Choose the right tool for the job, no? The thing is, static typing is never the job by itself.

"job" doesn't refer to static typing but the project you are working on. - script of 2,000 LOC to clean data => dynamic typing is fine => Python - web service of 1,000,000 LOC => static typing seems a better choice => Rust, Go, Kotlin, Scala, Swift, C#, Java…

A lot of people don't set out to write a million LOC web service, they build a smaller web service and it grows.

Re: A Failed Experiment with Python Type Annotations

#32
post #17

Earlier quoted context omitted.

"[...]You cannot annotate a function as returning `auto` in C++. `auto` and its variants in other languages are useful for eliding redundant type declarations. Especially long ones that use generics/templates. `auto foo = MyContainer >();` or whatever is nice than having to double write the type declaration. But, in C++ or java, if you write a function that returns a Mycontainer >, you have to write that in the funct…

Yuck, apparently I missed this happening. Its still (I think) true in java, where you can't have a function return `var`.

It’s only true if you have the function body available for deduction. Headers/decls need types.

Re: A Failed Experiment with Python Type Annotations

#33

> mypy has no trouble understanding this, but it’s unfortunately not valid Python code. You can’t refer to Node within the Node class. No, the workaround is to stringify "Node". class Node(Object): def add_sub(self, sub: 'Node'): ... def get_subs(self) -> Sequence['Node']: #Or maybe 'Sequence[Node]' works just fine. As of python3.7, this stringification is done by automatically under a from future import, and will ev…

> But you should still annotate your public apis. The good thing about inference (especially with a REPL) is you can write it without the annotation, and then use the inferred type (in Haskell, I usually find that when I resist the temptation to explicitly annotate types, the actual types are more general than I would have specified.)

In Haskell, I usually find the quality of error messages to be much worse without top-level annotations.

Re: A Failed Experiment with Python Type Annotations

#34

> mypy has no trouble understanding this, but it’s unfortunately not valid Python code. You can’t refer to Node within the Node class. No, the workaround is to stringify "Node". class Node(Object): def add_sub(self, sub: 'Node'): ... def get_subs(self) -> Sequence['Node']: #Or maybe 'Sequence[Node]' works just fine. As of python3.7, this stringification is done by automatically under a from future import, and will ev…

There's a great 5m lightning talk from Pycon 2019 explaining the difference between pytype and mypy[0]. It's great that there's different libraries approaching the problem from different angles. Speaking of which, I'm also curious to see how Facebook's Pyre[1] differs from the former two. I'm surprise there's isn't a comprehensive comparison of the 3 libraries yet.

[0] https://www.youtube.com/watch?v=yFcCuinRVnU&t=38m25s

[1] https://github.com/facebook/pyre-check

Re: A Failed Experiment with Python Type Annotations

#35
post #31

Earlier quoted context omitted.

"job" doesn't refer to static typing but the project you are working on. - script of 2,000 LOC to clean data => dynamic typing is fine => Python - web service of 1,000,000 LOC => static typing seems a better choice => Rust, Go, Kotlin, Scala, Swift, C#, Java…

A lot of people don't set out to write a million LOC web service, they build a smaller web service and it grows.

Quite. My company is using Go for most new projects, but we have five years of Python code that we can't justify rewriting any time soon. We've been able to add annotations incrementally instead.

Re: A Failed Experiment with Python Type Annotations

#36
post #19

I recently added type annotations to my Python 3.7 project and found it very helpful. Just the process of adding the annotations caught a handful of bugs! Some things I found useful: 1. from __future__ import annotations As I mentioned in another comment, this lets you write annotations naturally without worrying about when something gets defined. 2. typing.TYPE_CHECKING is only True while type checking. This allows…

If your code doesn't need to be py 2/3 compatible it's fine to annotate using str. But if you do, typing.Text and bytes is better.

Re: A Failed Experiment with Python Type Annotations

#37
post #4

I would have to disagree with this post (first point is actually inaccurate and the second I could go either way on). Type annotations/mypy, especially when coupled with dataclasses/pydantic has been very helpful in maintaining a rather substantial 3.7 codebase.

> rather substantial 3.7 codebase

What size codebase is substantial?

Re: A Failed Experiment with Python Type Annotations

#38
post #26

Why would you keep Python if you want static typing? I mean, there are several modern, performant (more than Python actually) statically typed languages. Rust, Go, Kotlin, Scala, Swift… All of them are mature and have a good library ecosystem. So, except if you need some math/AI/ML packages available only for Python, why bother? Choose the right tool for the job, no?

Scala: Python + dataclasses [+ mypy] offers a programming experience close to pragmatic Scala. The tradeoff becomes: * worse performance * lack of immutable vectors, alleviated via style conventions * rarely, awkward lambdas vs. * wide pool of people familiar with the language * lack of JVM lockin: Scala native is not there yet, the library ecosystem is all JVM. * [good] batteries included * much better reflection *…

No immutable vectors in Python? Are you not aware of tuples?

Lambdas in Python are quite limited, but offset by natural nested local functions.

Regarding performance, that's not always an issue, and depending on the use case can be addressed with async/await or using a multiprocessing pool. I have had issues with multiprocessing and some DB libs ib the past, but recently have had pretty good success.

Multithreading is still an issue because of the GIL (global interpreter lock) and really only useful if you're calling into a C/C++ lib that releases the lock while it does it's native things.

I've written a lot of Python in the last 15 years, and Ive written a ton of scripts that are faster than a well written identical C/C++/C# app, and was written in 1/10th of the time. It just depends on the use case.

Re: A Failed Experiment with Python Type Annotations

#39
post #36
post #19

I recently added type annotations to my Python 3.7 project and found it very helpful. Just the process of adding the annotations caught a handful of bugs! Some things I found useful: 1. from __future__ import annotations As I mentioned in another comment, this lets you write annotations naturally without worrying about when something gets defined. 2. typing.TYPE_CHECKING is only True while type checking. This allows…

If your code doesn't need to be py 2/3 compatible it's fine to annotate using str. But if you do, typing.Text and bytes is better.

Good to know, but I hope to never need this.
Post reply on HN