Fundamental difference between static and dynamic: static typing disallows writing a certain set of perfectly valid programs while also having the advantage of disallowing many invalid programs. So the question becomes: how badly do you want to work in that space that is not permitted by static systems?
And that space is where your data itself is highly dynamic. When you just want to represent data as maps, do generic operations on maps, then spit out more maps back to something else. This description applies to many many real world systems, particular in the more business-type domains.
Another space where dynamic really shines is dealing with relational data in a relational way. Relations are just sets of maps, the most natural thing in the world to work with dynamically. In a dynamic language I can just write code that peaks into the map, transforms certain fields, then passes the whole thing on down the line. I don't care what combination of selects and joins got me that relation, and in reality there will be many, I want to reuse my functions regardless. Although this is where more structural type systems can help ease the pain over nominal type systems.
I feel like this is a great blog post talking about the downsides of static typing in a real world system: https://lispcast.com/user-wizard-scenario/. I appreciate that the author has real world experience with both Haskell and Clojure and comes from that perspective.
Ultimately I'd say that if a program can be written in a static language, it should be, however some programs deal with information that just defies fitting into your type system without herculean efforts. Just like static languages will look down on dynamic languages for reimplementing poor ad-hoc type checking, dynamic languages can also look down on static languages for poorly reimpelmenting dynamic behavior with a bunch of functions mapping Any to Any.
And that space is where your data itself is highly dynamic. When you just want to represent data as maps, do generic operations on maps, then spit out more maps back to something else. This description applies to many many real world systems, particular in the more business-type domains.
Another space where dynamic really shines is dealing with relational data in a relational way. Relations are just sets of maps, the most natural thing in the world to work with dynamically. In a dynamic language I can just write code that peaks into the map, transforms certain fields, then passes the whole thing on down the line. I don't care what combination of selects and joins got me that relation, and in reality there will be many, I want to reuse my functions regardless. Although this is where more structural type systems can help ease the pain over nominal type systems.
I feel like this is a great blog post talking about the downsides of static typing in a real world system: https://lispcast.com/user-wizard-scenario/. I appreciate that the author has real world experience with both Haskell and Clojure and comes from that perspective.
Ultimately I'd say that if a program can be written in a static language, it should be, however some programs deal with information that just defies fitting into your type system without herculean efforts. Just like static languages will look down on dynamic languages for reimplementing poor ad-hoc type checking, dynamic languages can also look down on static languages for poorly reimpelmenting dynamic behavior with a bunch of functions mapping Any to Any.