Live data from Hacker News

Reasons to avoid static type checking in Python

typing.readthedocs.io

41–50 of 60 posts

Re: Reasons to avoid static type checking in Python

#41

> Pleasing static type checkers requires a non-zero amount of busy work Heck yeah! Why would I want to find problems ahead of time when the whole thing could blow up at runtime with cryptic errors. Or better yet, no errors because I’m such a ducking elite programmer that I never make mistakes. Read the code. The code don’t lie! This is a lame, low effort blog post. Jesus Christ.

Your comment is incredibly hostile. They're expressing their opinion on the language they use and like. A language that's always been that way. I find it incredibly tiring that every language goes to the fase of people complaining it's not other language and fighting to change it instead of using another one.

Re: Reasons to avoid static type checking in Python

#42
post #23

Earlier quoted context omitted.

Thats what I call "Uncle Bobs ossification disease" where you spend too much time on process and not enough on getting shit done. Because everything is broken up again and again it just piles and piles, making it harder to change things. Everything is intertwined through (often unwarranted) reuse and even the non-reused stuff is smeared over dozens and dozens of functions that are used only at a single call site. But…

If you saw how little code my projects require, you would realize that this is incorrect. I've built a decentralized cryptocurrency exchange that can work with most blockchains in just 5000 lines of code. Has been running for 4 years with zero bugs. I've written a cryptocurrency from scratch with only about 4000 lines of code and have not had any bug reported after 3 years of continuous operation. On the other hand,…

your lines must be long then or those projects featureless

Re: Reasons to avoid static type checking in Python

#43
post #28

I’ve written a lot of production Python and also a lot of thoroughly and rigorously statically typed code in C++. I use both regularly but there are clear tradeoffs in this regard. The main reason to avoid static type checking is that the programming language makes it difficult to do it effectively due to trading it away for other benefits. This does not change the intrinsic value of static type checking. Python work…

I’d probably agree with you 5 years ago, but in those 5 years typescript has shown that you can take a completely dynamic language, add a very powerful and well thought out type system and the resulting language is so much better for non-trivial projects. So if you ask me, who has been programming Python since before new-style classes, if types make sense for Python, the answer is a resounding ‘yes’: just steal as mu…

At first glance, JavaScript/TypeScript and Python seem like similar cases, but in practice, I have never found them to be so.

The JS/TS community has enthusiastically adopted static typing, to the point where (a) the type system in TypeScript is reasonably clean and intuitive for everyday work, (b) almost every major library uses static types and specifies them in its documentation, (c) almost all major tools and development environments pick them up and work well with them, and probably as a result of those things, (d) almost everyone now uses static types extensively, at least for new development.

The Python community seems far more hesitant. I don’t know why. Maybe it’s because we’d just had such a long transition from Python 2 to Python 3 and introducing static typing feels like another big change? Maybe it’s because Python’s static type system simply hasn’t been as clean and tidy as TypeScript’s, particularly before the recent generics changes in 3.12? Whatever the reason, in practice none of (a)–(d) above reliably holds in the Python world. Personally I do still prefer to use static types in new Python code, but it’s frustrating and often needlessly time-consuming when popular libraries don’t.

Re: Reasons to avoid static type checking in Python

#44
post #23

Personally, I don't use type checking because the benefits are extremely marginal given how I write software. - I avoid complex function/method interfaces. My coding philosophy revolves around relying on simple primitives as arguments and return values and keep complex state fully encapsulated. - I use a TDD e2e approach which gives me excellent code coverage and catches 'type mismatches' early as such issues cause f…

Thats what I call "Uncle Bobs ossification disease" where you spend too much time on process and not enough on getting shit done. Because everything is broken up again and again it just piles and piles, making it harder to change things. Everything is intertwined through (often unwarranted) reuse and even the non-reused stuff is smeared over dozens and dozens of functions that are used only at a single call site. But…

Very fragmented codebases like that have turned "inline function/method" into my favorite automated refactoring. I'm not an IDE person generally, but I open one up for that specific use. My favorite game to play is to see how many times I can inline with unchanged or net negative lines of code in a commit.

Getting rid of dumb tests is often where the real line savings is. No need to test your specialized internal function that's just wrapping filtering an array. Like, yes, array filter does in fact filter according the predicate you give it.

Re: Reasons to avoid static type checking in Python

#45
post #28

Earlier quoted context omitted.

I’d probably agree with you 5 years ago, but in those 5 years typescript has shown that you can take a completely dynamic language, add a very powerful and well thought out type system and the resulting language is so much better for non-trivial projects. So if you ask me, who has been programming Python since before new-style classes, if types make sense for Python, the answer is a resounding ‘yes’: just steal as mu…

At first glance, JavaScript/TypeScript and Python seem like similar cases, but in practice, I have never found them to be so. The JS/TS community has enthusiastically adopted static typing, to the point where (a) the type system in TypeScript is reasonably clean and intuitive for everyday work, (b) almost every major library uses static types and specifies them in its documentation, (c) almost all major tools and dev…

[deleted]

Re: Reasons to avoid static type checking in Python

#46
post #28

Earlier quoted context omitted.

I’d probably agree with you 5 years ago, but in those 5 years typescript has shown that you can take a completely dynamic language, add a very powerful and well thought out type system and the resulting language is so much better for non-trivial projects. So if you ask me, who has been programming Python since before new-style classes, if types make sense for Python, the answer is a resounding ‘yes’: just steal as mu…

At first glance, JavaScript/TypeScript and Python seem like similar cases, but in practice, I have never found them to be so. The JS/TS community has enthusiastically adopted static typing, to the point where (a) the type system in TypeScript is reasonably clean and intuitive for everyday work, (b) almost every major library uses static types and specifies them in its documentation, (c) almost all major tools and dev…

While there are countless cultural and technical reasons why TS ended up more successful than Python here, I think the single most significant aspect was that TS decided to go with structural system while Python went with nominal. While nominal systems in general are fairly popular and well-received, the chief thing here is that structural types match how the language was being already used. Especially for Python they had before embraced "duck typing" as their idiom and nominal types are in conflict with that.

Re: Reasons to avoid static type checking in Python

#47
post #40

Earlier quoted context omitted.

It doesn't work very well for generic concepts. For example, let's say I have a dependency which exposes a function which takes a URLDefinition as an argument. Maybe the dependent logic already has a similar type to represent URLs but maybe it's called URLInfo... The property names might be slightly different. Maybe URLInfo has a Host and Port property starting with capital letters but URLDefinition properties are al…

The approach you suggest is commonly referred to as 'primitive obsession' and is considered by many (including me) to be an antipattern. Having primitives everywhere means you have to repeat validations everywhere, methods will have more parameters, and it's much easier to accidentally pass these parameters in the wrong order.

You can pass simple 'info' objects. So long as they're just raw objects/data and don't expose methods. The main idea is that interactions between components is about messaging/communication.

Parent components give their children the necessary info to do their jobs but the implementation details of how they do it is fully encapsulated within the children components.

When components start passing other components to each other, they're no longer merely communicating with each other, but they are attempting to micromanage each other's functionality. It's a failure of the separation of concerns principle. There are always alternative approaches; for example, the child can emit/trigger an event to let the parent component know that a low-level condition occurred, but let the parent decide how to handle it because the parent is responsible for that higher level of abstraction.

This is not a new concept I invented, it's essentially what Alan Kay (the inventor of OOP) said decades ago. He said that OOP is about messaging.

There can be exceptions to the rule, but the idea is to keep those exceptions to a minimum.

Re: Reasons to avoid static type checking in Python

#48
post #46

Earlier quoted context omitted.

At first glance, JavaScript/TypeScript and Python seem like similar cases, but in practice, I have never found them to be so. The JS/TS community has enthusiastically adopted static typing, to the point where (a) the type system in TypeScript is reasonably clean and intuitive for everyday work, (b) almost every major library uses static types and specifies them in its documentation, (c) almost all major tools and dev…

While there are countless cultural and technical reasons why TS ended up more successful than Python here, I think the single most significant aspect was that TS decided to go with structural system while Python went with nominal. While nominal systems in general are fairly popular and well-received, the chief thing here is that structural types match how the language was being already used. Especially for Python the…

This is my single greatest complaint about Python's type system. Protocol should have always been the primary building block rather than just being relegated to something you use for "duck typing". Subtyping fits much better with things like the dynamic approach of the Django ORM, for example.

Re: Reasons to avoid static type checking in Python

#49
post #42

Earlier quoted context omitted.

If you saw how little code my projects require, you would realize that this is incorrect. I've built a decentralized cryptocurrency exchange that can work with most blockchains in just 5000 lines of code. Has been running for 4 years with zero bugs. I've written a cryptocurrency from scratch with only about 4000 lines of code and have not had any bug reported after 3 years of continuous operation. On the other hand,…

your lines must be long then or those projects featureless

Not so, they're quite short and feature-rich. When I read the code of most other people's projects, I'm often shocked at how over-engineered they are. A lot of code merely wraps some other logic or there are unnecessary abstractions which add unnecessary layers of indirection.

Re: Reasons to avoid static type checking in Python

#50
I'm not really sure what is meant by "avoiding static typing" in Python -- it's just like saying "avoiding unit tests", which is done by not running them (or even writing them) in the first place.

Python is strongly typed, but it does not mandate static type analysis -- unlike most other typed languages, where it is mandatory at compilation time. But if you choose to use it, there are tools which will run it for you at any point in time (mypy being the reference implementation). You don't even have to write any special annotations for that: the checker will try to infer the type when possible, or use Any when it isn't.

The crucial thing to understand is that Python is still dynamic at runtime -- there are no checks that an argument is of the correct type defined for the corresponding parameter. So your program can fail the static analysis but correctly run in practice, unlike most other statically checked languages.

Another effect of the above, which is often overlooked, is that many developers tie themselves into knots to get the type annotations right on unit tests. This is completely missing the point, as unit tests and static typing are at completely cross purposes: while static analysis evaluates, as the name implies, the code in its static state, the unit tests only make sense when they are executed, i.e. at runtime.

So the practical rule of thumb, learned from practice, is:

1. Regularly run the static analysis on your application (and library) code, adding any necessary annotations, to weed out various problems that might arise from mismatched types.

2. Write thorough unit tests -- ideally with plenty of property tests with tools like hypothesis [0] -- and run them regularly.

[0] https://hypothesis.readthedocs.io

Post reply on HN