If you’re using validate in the definition I just gave then this is simply not true. Program boundaries are always loosely typed, even in static languages, and if you don’t have runtime validation in your static typed languages you’re opening yourself up to all kind of issues and program crashes as well. You need to implement custom runtime validation at the IO boundary in all languages, even statically typed ones.
If you meant it in the definition I gave for assertion, that’s true to a limited extent, I still find extra assertions would be benefitial in statically typed languages as well. Asserting more on properties, like checking it’s positive, not empty, contains a certain number of elements, etc. still has value. Generative testing is still benefitial as well. And finally, I find the schema definition of most statically typed languages isn’t good enough for all use cases. Especially I find it can’t handle options very well, things like if a field value is X then Y is required, but if it’s Z then Y is optional. The kind of scenarios multi-spec solves for.
That’s why I’d love to have something similar to spec or malli even in Java, to make validation of IO boundary easier.
My feelings for the internal assertions of a program is that tests catch most of them anyways. Tests are assertions when you think about it as well, of specific input scenarios, that’s why I like generative testing and the function spec that can assert properties of input to output.
You’re going to have tests anyways, so either that’s good enough and don’t bother with more, including the extra type shenanigans of a statically typed language, or it’s not enough and then static typing similarly isn’t, what you need then is even stronger assertions of properties and generative testing, or proofs that can similarly assert stronger properties.
What static types are good for in my opinion, contrary to popular belief, isn’t correctness, because of what I just explained, but it’s refactoring and auto-complete. (with some exceptions, Rust provides a lot of valuable correctness checks when you don’t have a GC through it’s static type system for example)