Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

To add a couple of fun points about Haskell:

* QuickCheck!

Imagine you implement some function. As a trivial example, let's say you wrote a plus operator (spelled as (+) when not being applied). One of the properties it should have is associativity.

To check whether it is associative, you can write (in the GHCI repl):

  > import Test.QuickCheck
  > let associative op x y z = (x `op` y) `op` z == x `op` (y `op` z)
  > quickCheck $ associative (+)
  +++ OK, passed 100 tests.
QuickCheck just applied our "associative" function with 100 various random triplets and made sure that (+) behaved associatively in all the examples.

Now, the (-) operator is of course not associative, so let's see what QuickCheck says about that:

  > quickCheck $ associative (-)
  *** Failed! Falsifiable (after 2 tests and 1 shrink):     
  0
  0
  1
QuickCheck now spells out a simple example triplet (x,y,z = 0,0,1) which breaks the associativity claim.

This kind of testing is called "property testing" and is an awesome way to test pure functions that finds bugs far more easily (and more thoroughly) than traditional UTs.

For more "real-worldy" examples, consider QuickChecking that your URL parse function is reversible (build back a URL from the parsed components). Ditto with any kind of parser/builder or [de-]serializer.

Most pure functions are expected to obey various laws, and QuickCheck is a great way to verify they do.

* Parallelism annotations!

Sprinkling `par` annotations on your code (or replacing `map` with `parMap`) is guaranteed not to change the semantics of your program. It may speed up (due to extra parallelism) or slow down (due to extra overhead), but it is safe to throw it around.

* Type safety

No null dereference errors (though this is finally getting to some mainstream language). Exhaustive handling of all inputs can easily be verified by the compiler. Data types that describe your data precisely and yet more concisely declared than imprecise data types in other languages. Advanced features allowing to use the type checker to get more compile-time assurances (e.g: Red Black Tree respects all the RB invariants).

* Expressiveness

The kind of abstraction power Haskell gives you is quite unique.

A nice example of this is shown in:

http://www.haskellforall.com/2013/05/program-imperatively-us...

  fireBreath target = do
      lift $ putStrLn "*rawr*"
      units.traversed.(around target 1.0).health -= 3
This updates the game state by traversing all the units whose distance from target <= 1.0, and subtracts 3 from their health. This kind of expressive power is based on library-level abstractions (here, the lens library) with no language support or even macros.


And for those not lucky enough to use Haskell - there are QuickCheck equivalents in other languages too - ScalaCheck, FSCheck etc.




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

Search: