When my product manager comes to me and says "I want a button here that when you press it, it add the user-entered value in input box 1 to the value in input box 2."
Okay, done:
(button :on-click #(+ (box1-value box2-value)))
All I had to know was that the function contract/semantics of "+" is that it adds two numbers. Now I am done.Let's say that night I wake up sweating realizing that the user could type in the String "one" and "two".
Thankfully this before my push to production, so I go re-implement "+" to support English numbers.
Okay, now I go live. Well, now my user types in roman number "I". And a weird value is produced.
My product manager doesn't care about this class of users, so great I do nothing.
The point of this is that every step of the way, my choice to type check or not is a la carte. Not forced down my throat. Types are my tool, not my religion.
Clojure does have a few features that support dynamic dispatch, so there may be some games there to play as well.
The key point though is that "+" is really just my name for something that "adds two numbers together" -- that is strong enough semantics for me to express my function/business problem in terms of it. How I grow the supported range of that function...there are a number of ways I could go about that.
There are genuine arguments between static and dynamic typing. The assumed annoyance of writing type signatures is only a valid point for specific type systems such as Java, and is certainly not a generic concern.
As usual: https://ro-che.info/ccc/17