3 ms·
I moved (very roughly) from Java to Python to Haskell. When I was coding in Python if you asked me what percentage of bugs I encountered could have been caught
by lgas 6y ago
I moved (very roughly) from Java to Python to Haskell. When I was coding in Python if you asked me what percentage of bugs I encountered could have been caught by types, I would've probably said about 10%. Because I would've been thinking about types in Java and errors like calling "length" or a string and then accidentally calling "length" again on that int value from the previous call to length.
Now that I am working primarily in Haskell if you ask me the same question I would say probably about 90%. Not only does catching the "calling length on an int" types of errors at compile time but it gives you whole new tools (newtypes, Sum types, mtl-style constraints) for expressing complex concepts in a simple manner in the type system.
And all of these tools result in having to spend much less time thinking about things I had to think about in python, leaving me to spend more time thinking about the business logic which reduces the number of logical errors (which obviously can still occur).
As a concrete example I transliterated some Python code that someone was asking about on reddit into Haskell here:
https://gist.github.com/lgastako/f7465339214c6fde0fd75f4e488b447a https://gist.github.com/lgastako/f7465339214c6fde0fd75f4e488...
You can see on line 57 "unless (status == Fresh) $ do" -- I originally wrote checkStatus as a function that returned a boolean and the expression was "unless fresh $ do" but I replaced the boolean with a tri-valued sum type and rewrote the check against the value "Fresh" -- this avoids the boolean blindness problem and makes it much harder to get the condition wrong -- and while it's still possible to get the condition wrong, it's much easier to find it when you do.