For the record, duck typing is the way. Mypy is a curiosity to me; I'm happy those who need it are getting that itch scratched; I'm happier it's boxed away from what I work with.
For the record, duck typing is the way. Mypy is a curiosity to me; I'm happy those who need it are getting that itch scratched; I'm happier it's boxed away from what I work with.
Inside a function you need modify, you are passed a foo. What can you do with it? Take the length? Add a number to it? You don't know unless you know the type, and then the only place that info exists is in your head. Why not write it down in a way that can be checked and therefore never get out of date, like comments or some weird reincarnation of Hungarian notation?
As a bonus: Editors will tell you when you are passing incorrect types to functions before you even run your tests. No more strings accidentally treated as lists!
I am now absolutely convinced that types are important, even in python.
The overhead is as much or as little as you like.
One difference may be if you primarily work in your own projects or work with other people’s projects. And how skilled the other developers are. In my own projects I instinctively know the types, but not in other projects, and having the types documented allows me to make changes much more quickly.
Type-advocates throw this around all the time as if it's not the most patronizing thoughtpattern. Yes, I work on a good sized project with another 15 engineers using Python for the backend and angular for the frontend. If scale were going to reveal something dramatically different than whatever toy algorithms you might imagine I'm playing with...it would've happened by now.
What I meant was more along the lines of “do you regularly jump into the deep end on new projects that were started/maintained by someone else?”
Doing that is what made me a believer. Jumping into my current project, taking over from some else, was a nightmare without types. I had no idea if something was a string, a dict, a dataclass, a custom class, etc, with only vague hints based on how it was being used. These obviously had “types”, and the functions were designed for only one set of types. I just couldn’t remember what.
“Your own” doesn’t necessarily mean small or toy. But more about consistently working in familiar code bases where you are already familiar with what types are flowing around.
I think of these kinds of types as enforced documentation. It’s not for you (necessarily), it’s for other people.
If mypy is doomed to remain marginal it is because it picked a poor type system for the language it tries to support, not because stricter typing generally is the wrong choice for that language.
I don't think this has to be the case. If it got serious investment and the Python community was more open to making ergonomic syntax improvements so type annotations could be natural, we could see improvement. Similarly, I think it would need to figure out a saner solution to finding/loading type annotations, because the current set up and error messaging are immensely painful. I also don't know if Mypy will ever be sufficiently performant so long as it's written in Python (I think people really underestimate the difference between instant feedback and a delay of several seconds). Having good editor support would also drive adoption.
If Mypy were able to improve on all of these distinct problem areas, I think more people would opt into type annotations naturally, but it certainly feels like Mypy is being treated as a thing to pacify the people who whine about static typing (of course I don't think that's the real intention, only how it comes across).
What's more, with static typing your IDE can provide you with more helpful guidance by immediately showing you the valid method names associated with an object, type-checking their parameters as you use them, and suggesting possible parameters of the required types from the variables currently in scope.
With dynamic/duck typing, you give all that up -- for no clear advantage.
Use static typing in a project of significant size. Always.
And introducing complexity you have to resolve before your program even runs too! Complexity you have to solve. Static typing systems require you to do more design upfront. And more importantly, in your head! The most you can do is run your compiler and it'll tell you if you got it right. If not, just try again!
Dynamic systems will encourage you to code flexibility from the beginning. You may have to run your system to expose a class bugs...but so? I was going to run it anyway.
All these conversations are just about moving work around and when it gets done. Most problems are solved equally by a dynamic or static type system. However, static type systems inherently require more boilerplate. At the end of the day, you just rarely need it to do anything of importance.
The formalization step also allows you to encode business logic, where it would not otherwise exist. Suppose you have a system with documents. Every document has a length property...today. So in an untyped codebase, you've been doing just fine assuming it exists, and "just running the code" has found no issues. But technically, it doesn't always exist, and this fact isn't encoded anywhere. It breaks. If you had just defined a document type, then you could simply update the length type and let mypy tell you literally all the places where the bug would arise. Or, it would have allowed you to avoid making that assumption in the first place, rather than trying to make sure every developer memorizes this useless fact and writing tests every time the length property is touched.
You've baked your conclusion into your argument. But by this logic, sure, everything is typed. I'll buy it. A static type system just makes you explicitly type it out for every single thing and again for every single thing that might operate on that first thing. It's pedantic, filled with boilerplate, and plenty of promises about problems the system solved that were just invisible before. Hmm...those might be the marks of snake oil, now aren't they?
Consider a iron foundry. Are there type checks on the iron? No, the entire process is duck-typing. Why? Because that's how reality works. You can specially shape your iron ingots to key into your foundry. What's that? Duck typing. The firing profile will follow certain characteristics. Did it get those characteristics from the ingot? No, it duck types it and starts firing it as if its iron. If it isn't iron, the process will throw an exception. And that part has all sorts of safety checks around it. The most you can do would be some type of chemical check on the ingot before starting. Almost like a typecheck before proceeding in a method.
Aristotelian vs. Platonic approaches. The problem with the Platonic approach is that it requires you to be an oracle. Static typing is like trying to encode logic at the molecular level. This atom WILL NOT bond this atom. I mean, sure, it can work...but there's a lot of atoms and a lot of interactions. Don't define what you don't need.
Yes there are, it's called physics haha. The iron foundry analogy is not great imo. Programming is more akin to building an engine, but also building the tools that are used to make that engine. Because of the physical nature of these tools, you get a simple static type system by default: you cannot put a screw into a hole not meant for the screw with that thread. Now imagine you didn't have this guarantee. Any tool could technically be put anywhere, and you wouldn't know you had it wrong until you ran it and it killed you. Or even worse, it seems to run fine until you go over a bump, then it kills you. That's duck typing without a type system.
And god forbid you need to add more engineers to your engine project. Nothing is documented, and they have to infer the properties of the tools based on how they are used today.
That's half of duck-typing. You're missing the exception response where safety is enforced. A static type system fails with the wrong type. A duck-typed system responds with something as sensible as it can reason with what it was handed. Must often, that's a hard failure because most code is brittle and doesn't need the robustness (i.e. don't build what you aren't going to need).