Earlier quoted context omitted.
Easier to pick up, harder to use. A spade is easier to pick up than a digger, but try digging foundations with a spade.
Is it though? I've been using dynamic langs my entire career, and static ones too! I feel like statically typed langs, (I'm looking at you Java), are a bit more stubborn to work with, especially around API design, prototyping, greenfield stuff. I do like langs like Haskell and Standard ML where they are statically typed, the the type system is mathematically sounds, and the types are inferred. I want my type system t…
* Reading and understanding code is much easier because the types are written down. You spend much less time figuring out what variables can contain.
* Navigating code is much faster because tools like go-to-definition, code completion and find-all-references work reliably
* Refactoring code is a lot easier - or in large projects actually tractable. In large dynamically typed projects something as simple as renaming a variable can be an impossible task.
* Obviously the one people talk about most is catching bugs. The degree it does that depends on how strong the typing is (e.g. Rust will catch many more bugs than Java). But they will all catch the embarrassing things that dynamic languages can't like typos and missing arguments.
If you've only ever written short greenfield projects you might not appreciate some of these benefits as much as you should because you wrote all the code yourself so all the details are still in your head. It's a bit like saying seatbelts are an unnecessary pain because you haven't ever been in a crash.
> types are inferred
Some local type inference is good, but Haskell / ML style global type inference is kind of the worse of both worlds. You have to satisfy the type checker, which is harder because global solver errors are always harder, and you don't get the documentation benefits of static types because the inferred type is frequently a generic type.
Rust went with local type inference only for very good reasons.