Hacker News new | past | comments | ask | show | jobs | submit login

Isin't that true for statically typed languageS?



Its not in generally; statically-typed languages (e.g., C, C++, Java) make impossible certain classes of runtime errors that occur in dynamically-typed languages, but don't actually reduce the need to test each path through the code you've written to assure correct results, nor do they reduce the number of defined paths through the code assuming that the defined interface is adhered to (they make it impossible to not adhere to certain parts of the advertised interface, but even in a dynamic language you don't need to test undefined cases, as there is nothing to verify, so that doesn't actually narrow the test surface.)

Haskell's type system and syntax are richer in ways which I think makes it possible to unambiguously describe more results in code in ways which makes unit testing certain aspects superfluous. I'm skeptical of most "you don't have to test" claims, but I can see more of a case for reducing the need for testing with Haskell than with many other statically-typed languages.


Partially, but not the the same level as Haskell. It's pretty easy to get broken code past the compiler in C# for example.


Could you give some concrete examples?


First example is nullability. Anders says ~50% of production issues with c# involve null deference errors. Haskell tags in compile time which types may or may not be null.

In c# if your method is supposed to return one thing and set an object attribute of another, and you forget setting the attribute, the compiler won't help.

In Haskell, you don't use mutability much, instead you return both things. If you forget to return it you get help from the compiler.

Another example: in Haskell, you write a sort function but you forget to handle the base case (always returning an empty list instead). You get an inferred type like:

  sort :: Ord a => [a] -> [b]
Which tells you you forgot to actually return the elements.

Another example, in Haskell you can represent a red black/avl/b tree while also type encoding all the invariants.

For rbtree this type level encoding is about 7 short lines long.

Then all the dozens or hundreds of lines of code implementing the tree are guaranteed to maintain the invariants, no unit testing needed at all.

Another example, ST is a monad that let's you write deterministic imperative computations that can be wrapped with a pure interface (hiding the imperative innards). A small RankNType and a phantom type are used to tag both the ST computations and the mutable data, giving a compile time guarantee that mutable data doesn't leak between different computations. This guarantee means you can trust ST computations to actually be independent and thus the pure interface is safe.


Thanks! Some of those I knew from OCaml.


NullReferences in C# (and lots of other languages).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: