Are you proposing that a distinct `assoc-in` function should be written for every combination of types you'd need in your program?
Doesn't that rather prove my point that some functions that are trivial to write in a dynamically typed language are hard to write in a statically typed language?
"Come to think about it, assoc-in is a great example of why I want static types. It's very hard to figure out what that function does from reading the documentation."
I've always thought the function was trivial. I mean, it's just four lines of code:
(defn assoc-in [m [k & ks] v]
(if ks
(assoc m k (assoc-in (get m k) ks v))
(assoc m k v)))
I have a much harder time relating back a complex type signature in Haskell back to what the function actually does, but perhaps that's something that just requires more practice."But you have to write the specs."
Sure, but you have to write the type signatures, too. Type inference certainly cuts down on a lot of work, but it doesn't entirely eliminate the need for explicit typing.
I also tend to prefer adding explicit type signatures, even for functions that could be inferred. It makes type errors easier to catch.