Why I still Lisp
&gt;<i>I have never had a static type checker (regardless of how sophisticated it is) help me prevent anything more than an obvious error (which should be caught in testing anyway).</i><p>Obvious in retrospect is not the same as obvious. And such errors happen all the time, the same way without syntax checks typos happen all the time.<p>And &quot;caught in testing&quot; is 2 extra steps removed from caught immediately by the syntax checker running as you type or save: writing the tests and running the tests (and being thorough&#x2F;lucky enough that this part of the code is covered in a test).<p>&gt;<i>But it is a stupid tool. It can only do so much. So, you now end up with artificial rules about how to satisfy this tool. And things that I know (and can justify or even formally prove for my use cases) are perfectly fine to do are suddenly not.</i><p>What thing that violates a type check would be &quot;perfectly fine to do&quot;?<p>Dynamic languages still have types (since you still need to pass around the right object with the right methods or fields to the call site, else it will raise an exception when you use a method&#x2F;access a field&#x2F;run a function on the wrong type).<p><pre><code>  def square(value):
     return value*value
</code></pre>
If value is not a numeric type, square is not going to be happy. And that&#x27;s the case with most (all?) dynamic code.<p>What would be a counter-example that something not satisfying to a type checker would be &quot;perfectly fine to do&quot; in a dynamic language?<p>(I do accept that the static typed language is better to have generic and&#x2F;or algebraic types, no make lots of invariants easier to express without ceremony).