16

This question arises out of the question https://softwareengineering.stackexchange.com/questions/25569/is-haskell-worth-learning

Generally a few often repeated statements are made, about how Haskell improves your coding skills in other languages, and furthermore, this is because Haskell is stateless, and that's a good thing.

Why?

I've seen someone compare this to only typing with the left hand, or perhaps closing your eyes for a day and just relying on touch. Surely there is more to it than that?

Does it relate to hardware memory access, or something else which is a big performance gain?

3
  • 2
    Haskell is academic. I would watch some lectures by Rich Hickey about Clojure - there he makes killer pragmatic arguments (similar to the 3 points by Javier, but also done in a simple way).
    – Job
    Jan 9, 2011 at 2:21
  • 2
    Yes, see clojure.org/state Jan 18, 2011 at 9:51
  • 6
    Just because Haskell is "academic" does not mean it's impractical or not pragmatic. Jan 8, 2012 at 21:13

4 Answers 4

17

there are at least three big advantages off the top of my head:

  1. it makes programs more close to mathematical expressions. In math, x doesn't change, you just don't know what it is until you solve the equation.

  2. In the end, there is state change (after all, that's how the computer works at low level); but it's confined by the language to specific places. that allows the compiler huge opportunities to move code around to optimize it, since it knows that it doesn't change anything that other code depends on.

  3. Concurrent code doesn't need to synchronize to access non-changing data, so concurrency is enhanced, both in SMP shared memory systems (all multicore systems of today), and on loosely tied clusters.

6
  • 3
    Propoennts of functional programming put most stress #3, i.e. easier concurrency proramming.
    – Mchl
    Jan 8, 2011 at 12:55
  • 4
    @Mchl: In my experience they put most stress on "It's easier to understand and reason about", which kind of corresponds to 1. Though I suppose that might differ between language communities.
    – sepp2k
    Jan 8, 2011 at 15:00
  • +1, very complete answer. @sepp2k: both are important I guess. Reasoning about a program is what we do daily, and it's true that if you don't have to check that the state has not changed in some deeply hidden function it's much easier to read only high-level methods and catch what's going on. Hardware-wise: since we're moving toward multi-core and multi-processors more and more (though I guess it'll be a while before home computers get multi-processors), having a language that facilitate concurrent programming is a premium. Jan 8, 2011 at 16:41
  • Good answer, #2 was what I presumed to be the answer, and although I've read often about multiprocessing advantages, it's rarely stated as clearly, great job.
    – ocodo
    Jan 8, 2011 at 21:36
  • 1
    @Yttrill, functional languages are not unique in their reliance on garbage collection and garbage collection is a lot easier when you are dealing with immutable data. Doing any computation on an instruction based architecture means modifying state, that doesn't mean that functional languages are somehow more difficult to parallelize. Functional languages rock at parallelism; lookup data parallel Haskell, it's a feature that would be almost impossible to add to an imperative language. Jan 8, 2012 at 4:24
4

Here is another advantage: reduced coupling. If you have code like:

 function doStuff(x) { return x + y;}

and elsewhere you have:

 function doOtherStuff(x) { y++; return y + x;}

then the two functions are dependent implicitly. There is no easy way to tell that calling doStuff is affected by calling doOtherStuff. Without mutable state, you would have to make the connection explicit.

Of course, this is not an issue with all mutable state--the issue is with pervasive mutable state. The real solution is to have immutability by default and some way of "marking" and constraining mutable state to just where you need it.

1
  • +1. Many experienced programmers know not to write code like the above and it's not a huge step to go from "mutable state is bad in this situation" to "let's seriously reduce the amount of state we mutable and write more functionally", but it's a step that disappointingly few make. Jan 9, 2012 at 8:25
2

A simplified answer is: when you see a name in a purely functional language you know what the associated value is by a simple lookup of its definition. If you have mutable variables, you can only tell by which of the several assignments to it was executed last, so you have to also analyse control flow, which in turn might be conditional, leaving you with multiple possibilities. To get an exponential explosion you only need to consider that the RHS of the assignments are themselves dependent on variables, so you have to recursively analyse them too.

The bottom line in the above analysis is that it is untenable without comments explaining the intent, invariants, and semantics: these may be hard to interpret, and it may be hard to verify the semantics are adhered to in the actual code.

This answer is basically an expansion of @Javier's point 1.

I think it is also an explanation of the popularity of the fraudulent OO regime: with OO the mutable state is encapsulated which makes analysis a lot easier by localising the mutations to some extent, and permitting much more robust expression of and verification of semantics.

Having noted that, functional programming is not the answer. The right answer is a system which supports both inductive (functional) and coinductive (procedural) programming, so the right tools can handle both stateless and stateful programming. It's just that the constructive (functional) theory is well established whereas the theory of state management is still in its infancy.

3
  • Mixing functional and imperative programming is exactly what Haskell does--normal functions are functional while stateful computations can be expressed with do-notation that lets you carefully isolate and control mutable state (among other things). This is why the language with the most practical STM implementation is Haskell. Jan 8, 2012 at 21:17
  • Do-notation doesn't really have anything to do stateful computation per se. Do-notation is just a simpler syntax on top of monadic function pipelines. Stateful computation is merely one of the things that can be expressed using monads, and hence do-notation. Jan 9, 2012 at 0:27
  • Mixed functional and imperative programming is what almost every language in existence does. Haskell may have provided a way to isolate the stateful parts, but that doesn't make it a proper mix: Charity is more like how it should be (IMHO).
    – Yttrill
    Jan 9, 2012 at 13:46
2

As the author of Siege, a DBMS written in Haskell, some may call my view on mutable state conflicted. I hope to show otherwise.

The purpose of mutable state is to describe the current state that a system is in. Say you have a blog and it is backend by a database, the database describes the posts that you have on your blog at the point in time at which you query it. How many posts exist right now?

Contrast this with immutable state that is used to convey facts. How many posts were there on 12th August?

Facts are easy to reason about, mutable state is not. However, mutable state is not some evil impure effect that should be banished from the reaches of ours minds; we often need it to coexist in the mutable world we live in, we just need to use it more sparingly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.