If you struggle with "speaking types" then that's an indication that you don't understand the domain of values your code works with. Having a solid plan for exactly what shape your data can take is empowering, not restrictive. To some extent, certain restrictions provide greater freedoms in the sense that you can make more accurate assumptions about your data without needing to perform a bunch of run-time checks or write hundreds of unit tests to ensure your code works in all possible situations.
I'm not sure I agree. I've met intelligent programmers who can elucidate the domain of values which their code is utilizing, but simply cannot do so in the framework of a given type system. Or perhaps they just find it difficult or painful to conform their description to the grammar of the type system. Understanding the data domain and being able to describe it in a specific type system are different skills.
Even if one is completely in favor of static types, it's important to be sympathetic to this point of view so that we can design better, more friendly type systems going forward.
There are definitely some failings in static type systems that can cause programmers to struggle, regardless of how well they understand their domain of values.
I guess I was thinking more of people I've talked to who advocate for dynamic type systems for rapid prototyping, because they don't want to be bothered to stop and think about their types first — they kind of just go with an approximate view of their data held in their head. I think this style of programming leads to a lack of understanding of the domain of values down the road, which is more what I meant to address. But I did not sufficiently explain this in my previous comment haha.
Totally! I wish we taught more type directed programming in general. It's a good way of thinking and can guide your process very nicely.
I've slowly come to the conclusion that instead of assuming my friend who doesn't like static type systems is misguided, I should try to figure out what aspects of static type systems need improvement so that a person like him would use them. Even if I don't agree with him, I can still use his point of view as a different perspective.
Ah yeah, that's a very pragmatic view on things! And totally reasonable. I intend to work on improving type systems, so this is definitely the mindset I strive to maintain more often than not haha.
I 100% understand where you're coming from, but I view this as an advantage of static type systems. The "pain" is you having to go through your code and make sure that you change your usages of given types to match the new definitions, right? This is forcing you to make sure your code is still correct with respect to the types.
Most dynamically-typed languages let you skip this part, but this causes you to lose clarity. Is your old code still correct? Or is it just mostly correct? Are there new unexpected edge cases being introduced that you didn't bother to go check on due to faulty now-outdated assumptions?
Changing your types is a pain, I agree. But programs are just about data transformations, and types are representations of the shape of those data. Changing your types without changing every part of your program that touches those types inherently means that your program is now running on invalid assumptions. Sometimes it works fine, but I think it is better to know it's fine than to just say "Well, it seems to work in most cases."
Refactoring when you change your understanding of the domain can be a lot of work also when you have dynamic typing and lots of tests, but if the tests are well designed, I rarely feel that as painful as it was when I felt I was battling with the type system.
PS: my main experience with static typing was with c++, it's possible that more modern type systems could have improved the situation.
What are their reasons?
With static typing I can just highlight a type / jump to the definition or get intellisense. I also find it useful when I have specific names for data types because I can reason about things / communicate them easier
To me taking the time to specify types or wrangle the type checker is worth the reduced mental burden of having to remember the shape of things, and refactor data structures confidently
A static type system ensures that, at the very least, all the types line up at compile-time. You find type errors much faster than with a dynamically typed language, and this can guide a much less exhausting development cycle.
I loathed dynamic typing mostly because you had to jump around code to understand what the shape of anything was, and it distracted me from the problem I'm trying to solve
In ML influenced languages types actively help me plan a solution, and rarely get in my way
When really, both styles have their value. Static types are very useful and do provide some nice safety. However, static types can also be quite annoying and force you to acquiesce to the type system. You have to learn to "speak" types, which can be very tricky. There's a joy that comes with the freedom of no static types.