Types also come with a lot of inherent complexity that you don't get with dynamic programs. Recently, I wrote a Type Provider for web Routing in F#, and it is orders of magnitude more complicated than what a dynamic approach would have been. It is nice that it is not possible to express a program that uses route parameters the wrong way, or provide a route that is unreachable, etc, but it takes a lot more work than a dynamic version with no such safety.
One domain where I think static typing is worth it is for parsing. After having used FParsec to parse a structure, and also having tried it dynamically, I felt the static typing added little complexity for all the safety it brought, so it was very much worth it. But there are also some dynamic parsing libraries that much easier to get started with, such as Instaparse, so YMMV.
Doubtless, there's another way to do this without a global / dynamic data tree, but this is working, at least for me.
I'm not sure if there's a library in F# similar to HXT, but in Haskell, working with large xml structures is a breeze.
Pascal and C admit structures whose elements are structures. However,
this requires that the programmer manipulate pointers explicitly, and
adhere to the restriction that each field of a structure can contain
only elements of a prespecified form. Unlike Lisp with its pairs,
these languages have no built-in general-purpose glue that makes it
easy to manipulate compound data in a uniform way.
With static typing, it's also difficult to write procedures that operate on arguments of which the type is none of the procedure's business.The thing is that any operation you are using on those arguments (of which the type is none of the procedure's business) can be described by an interface which the argument implements.
You're much safer knowing in compile time that the operations you'll use will be valid, instead of hoping something doesn't crash in runtime.
But again no massive ecosystem of libraries to simply plug in so unsure if 'secret weapon'. Also I have experienced the nightmare of trying to port non typed libraries to typed Clojure and falling into a rabbit hole of errors propagating. Haven't had the same problem with Racket but ecosystem is not even close to Clojure so anecdotes worthless.
But types are also what cause us to think with in the box i.e to say powerful type hierarchies, the ones that save us from writing boiler-plate are also the ones that are difficult to understand, and in Java, somewhat weird. Not to mention they are needlessly specific - Unless you have ML style parameterized types.
Also, note that if you are working in type safe language, does not mean you can escape writing tests. You still have to write tests.
Just like human body is not all bone, though it gives structure, nor a bridge is all steel, even though that is what keeps it together, likewise I don't believe all aspects of a project should be written in a strictly and statically typed language. Dynamic types have their niche, and the nice thing about dynamic types is you are just concerned with ideas aka abstractions instead of type algebra and its mechanics.
Once you have protected your interfaces(with a type safe language), you are past "Idk what i am reading" stage, and hence in a safer place to do type agnostic things - and the sweet thing with clojure and lisps, yeah sweet if you get it, you can almost always break what you think your ceiling of capabilities is.
Without types you just can't do much, or at least, if you're super good, compiler can't do much.
And most of the time you're trying to make something faster.