4 ms·
This is the opposite of my progression. I worked professionally with Haskell for 6 years and then Scala for 2 years at the early stages of my career. Static ty
by mlthoughts2018 6y ago
This is the opposite of my progression. I worked professionally with Haskell for 6 years and then Scala for 2 years at the early stages of my career.
Static typing is a waste of time that does not facilitate better design, better clarity or safer code. The classes of errors detectable and preventable with static typing are almost never very important, and in dynamic languages you can achieve the same results with lightweight unit tests that are no more effort, and often much less effort, than creating or maintaining type system designs.
Type annotations are code and more code is just more liability and more complexity. It really is just that simple. You should strive to write code with the fewest cognitive concepts necessary. Cognitive concepts are the hugest form of tech debt you can have in code, much much worse than repeated code, lack of modularity, lack of test coverage and so forth. Type system design invites running amok not just with all kinds of new cognitive concepts to model every domain problem, but also the code authors are encouraged to use “creativity” when developing these concepts, which leads to poorly factored messes that express the limited view of a set of specific people - often with huge premature abstraction that makes the code excessively brittle (even when it’s claimed to be extensible) and poorly suited to accommodate use case changes or requirements changes.
For the past 5 years I’ve moved on to exclusively using the Python ecosystem for system designs. It’s nice since I work in machine learning and no ecosystem even comes close to Python in terms of ML tooling, but even for backend systems and web service designs around the ML product my team creates, using Python has been pure joy in terms of easy development cycles, easy ability to write less code, easy ability to achieve high safety and reliability, easy ability to trade off safety as a resource to accommodate sudden business requirement changes.
I can sincerely say across the board programming large backend systems in Python has been more pleasant, easier to design, read, understand and maintain, easier to extend, and led to safer, more reliable delivered solutions than any of the projects I worked on using Haskell or Scala (even when working with those languages in mature organizations that had very seasoned, veteran functional programming experts establishing in-house development practices).
Now that I’ve transitioned through senior & staff engineer and became an engineering manager, my perspective over the years has come to endorse dynamically typed languages as vastly superior tools.
My experiences with Haskell and Scala just lead me to believe Python is strictly better for large system design.
- dpc_pw 6y agoLet me guess. You probably worked in small teams, mostly with code you co-wrote your whole carrier. You literary compare 3 languages that you happened to use and think that all there is to know about this argument.
- mlthoughts2018 6y agoNo, the Haskell job was in a large financial service firm with a huge investment in Haskell. Many people on the team were even experienced with GHC compiler engineering. The code base was very large and cross-org. All the other jobs have been in large ecommerce firms, again with large codebases cutting across the org, and separate pockets of “small project” development here and there. I also have many years of experience in C and C++, both of which are solid. I especially like writing systems in C because it’s easy to make it module oriented, and static typing doesn’t need to have anything to do with concept or domain modeling, yet you still can occasionally sprinkle it in with simple structs. I like C++ without classes or exceptions, but the language outgrew that way of using it. The best approach I ever saw to using Haskell at scale was to severely disallow any complex type system feature, like even disallowing lensing or custom type classes. Just ruthlessly stick only to basic language features and module oriented design. When you make your own data structures, never generalize them to inherit functionality through type classing, rather always rotely splay out a new module of all the functions and behaviors for operating on that data structure. Do not seek to endow it with any type of compositional behavior besides very basic plain function composition (eg no monadic behaviors).
- dpc_pw 6y ago> The best approach I ever saw to using Haskell at scale was to severely disallow any complex type system feature, like even disallowing lensing or custom type classes. Just ruthlessly stick only to basic language features and module oriented design. I agree. It's not unlike what you can do with reflections and other dynamic features of dynamicaly-typed languages. So it's not a problem of static typing itself. It's a problem of taking a feature of the language and strangling the code with it. I had to do some refactors of JS code where everything was a shapeless objects with random fields, as the language doesn't even nudge the developer into considerations like keeping consistent "shapes" of data. Had similar experiences with some Python code, where I had to fight both data types fuzziness, reflective-features inventions (hello __getattr__!) and OOP over-abstracted nonsense at the same time. One way or another, in larger teams/projects dynamic typing just doesn't scale. Type system works like a most basic documentation / developer aid / consistency encouragment, even if it is pushed into complexity nightmare. I don't think I've ever even seen a reasonably well working large project in a dynamically-typed language... IMO, static typing gets blamed for problems that are usually caused by OOP: complexity caused by needless abstractions (mostly inheritance taxonomies).