Sunday, April 14, 2013

Haskell... is great

Haskell is a great computer language.

It's great to use and it's great to learn even if you will be spending time mostly with other languages.  This is because it represents, in a very pure form, many of the fundamentals of programming - that is how logic, calculation and action sequences can be expressed.

Many modern computer languages are packed with different programming structures and idioms that are intended to be pragmatic; tools for different kinds of problem the programmer will encounter.  Haskell is refreshingly simple in both concept and syntax.  That's not to say it's trivial to learn however, mostly because we pretty much all get our education in languages derived from Fortran and Algol.  To use Haskell you have to rebuild your mental wiring about programming abstractions in the platform Haskell provides, and of course your repertoire of idioms and library functions that you'll use to get things done.

Aside from just 'being different' and intellectually interesting though, there are some deeper things that make Haskell a fitter computer language - especially as we enter a new age of multi-core and distributed computing.  The very premise of how Haskell works is genuinely better:

  • There is no 'naked' shared mutable state.  Shared mutable state is like 'original sin' ;-).  It complicates and corrupts normal life and has pernicious effects on larger bodies of code.  In the absence of concurrency, its effects are not debilitating - you just have to get the logical sequence of changes right.  With concurrency, all bets are off!      
  • There are no pointers and no NULL.  Whole classes of bug are effectively removed as possibilities in one fell swoop.  
  • Functions are pure and subject to more automatic optimization.  Functions are a mathematical concept.  True (pure) mathematical functions are subject to a century of deep mathematical understanding in how they can be optimised via simplification. 
  • Lazy evaluation allows for clean, naturally readable algebraic definitions.  Lazy functional languages grow by combining the expressions.  This acts like a powerful and nearly invisible glue.
  • Functional composition is the central idea of Haskell.  Composition is the only way to successfully build very large structures from smaller ones.  That's because it doesn't pollute the derived structures with constraints and special behaviour arising from the design artifacts and other properties of the method used to bind together the semantics (e.g. the glue doesn't have any other effect than joining expressions).
  • It has a very expressive static type system that supports many kinds of polymorphism and has type inference.  Haskell figures out the type of code you write.  If you want, you can write code without writing a single type annotation.  You'll get the most general meaning of your code inferred so it will be useable in as many places as possible.  However, if you actually make a typing mistake then the compiler will tell you right away and you don't have to wait until that code path is executed at runtime to find out (maybe months later!).  
As alluded to above, where this gets really exciting is how this can help with the biggest challenge of computing we have today: parallelism.  Haskell fundamentally has all the features and no critical impediments that allow a program to be arbitrarily broken up and distributed across multiple compute nodes (whether CPUs or machines on a network).  There is still a lot of work to be done to make this automatic, based on an analysis of cost of moving code and data, but even today more can be done on a single multi-core machine and the nature of the language makes manual structuring of code for parallel execution so much easier.

More and more computer languages are adopting functional and lazy evaluation features.  Lambda functions are being added that allow functions to be passed as values like data and generators are being added so that sequences of values can be computed on demand.  Languages and libraries have adopted Haskell-style list comprehensions, and even monads (a higher-level functional programming idiom).  Yet, even as these features are transplanted to other languages, they only add to the bewildering collection of programming features in those languages and often their addition forces certain compromises on their use.  At the very least, communities of programmers will have to select which language features to use and when.  The choice of programming style has a huge effect on the degrees of freedom that code preserves for future reuse.  Conversely, Haskell remains uniform - everything is a function, the only arbiter of reuse and recombination is the type system, according to the values that the program is manipulating.  Because Haskell is focused on basic values rather than abstract structures of state and state manipulators, it is sometimes called "value-oriented programming".

Whatever piques your interest about Haskell, I expect to post a series of blog entries here on learning Haskell... mostly as a side-effect of introducing the language to my son.  It will be (hopefully!) focused on Haskell as a practical tool, compared of some discourses that discuss more technical/mathematical underpinnings of Haskell's features.

No comments:

Post a Comment