> 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.
Reasons to avoid static type checking in Python
41–50 of 60 posts
Re: Reasons to avoid static type checking in Python
#42Earlier 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,…
Re: Reasons to avoid static type checking in Python
#43I’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…
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
#44Personally, 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…
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
#45Earlier 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…
Re: Reasons to avoid static type checking in Python
#46Earlier 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…
Re: Reasons to avoid static type checking in Python
#47Earlier 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.
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
#48Earlier 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…
Re: Reasons to avoid static type checking in Python
#49Earlier 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
Re: Reasons to avoid static type checking in Python
#50Python 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.