This is quite different than object oriented or even compiled imperative languages where type system constructs contain data and function units that represent internalized constraints.
In functional programming you set up types and their constraints such that the business logic you require is a derivable consequence of the system and any other outcome is as close to provably impossible as can be. The less of this you choose to enforce, the more “imperativy” or “objecty” your use of that functional language is.
In imperative or OO languages you choose to make atomic units that have internal structure, but whose behavior across the interaction of the units is not itself a derivable consequence of any more abstract set of rules. Not even interfaces or templates represent this - they govern how components can communicate but do not limit what components can do.
You use the program’s structures to carry out the required business logic, but you cannot truly prove you haven’t allowed for some different logic or edge case instead.
In this sense, safety is a resource rather than a requirement, and if you learn that a previously unsafe operation is now safe, because the real world circumstances changed around you, you are free to have your program units do the previously-unsafe -now-safe thing without needing to remove expensive abstractions that had been set up to cause the previous notion of safety to be a consequence of your program.
If I understand you correctly now, a functional language with no real type system (and thus no such compiler enforced constraints) like Elixir would be imperative in your book and therefore more suitable to facilitate constantly changing business requirements.
Thanks for taking the time to detail your thoughts for me!
Can you clarify if you mean that the type system gets in the way here, or the same would apply to even dynamically typed functional languages?
I'm trying to understand if you think a static type system is the hindrance here, or the language being functional in paradigm.