You get much more than type-checking from ML-style languages.<p>It's worth learning one of these languages well enough to understand the fundamental concepts at play. If all you can see is static type analysis and arcane signatures you haven't dug deep enough yet.<p>The renaissance of functional programming happening in JS is the only thing that makes me happy about working in that language. Having immutable.js, ramda, ramda-lens, redux, and various monads (such as data.task and data.maybe) makes my code much more effective than using the majority of JS's more dynamic features... and it doesn't even have static type analysis.
My alma mater's introductory CS course was entirely in Standard ML, and was a great (if occasionally painful) way to learn some of the fundamentals of CS without requiring any background knowledge.
Julia is interesting in this regard (and Go I think - I used it's ancestor: Limbo). You can start with<p><pre><code> function foo(bar)
pass
end function
</code></pre>
and then add types later when you've found out what was inferred<p><pre><code> function foo(bar::Int64)
pass
end function
</code></pre>
I enjoy this style, it means I can create the story as I go along without re-writing types every time
> people routinely seem to get confused as to whether something is a value of a type, a strategy for producing values of that type, or a function that returns a strategy for producing the type.<p>In other words, they aren't sharp enough thinkers. It's the same problem as conflating singleton lists or sets with their lone element, constant functions with their output value, or “any list” with “list of anything”. Dijkstra put it quite nicely:<p>> About the use of language: it is impossible to sharpen a pencil with a blunt axe. It is equally vain to try to do it with ten blunt axes instead.