Chapter 1. Why Functional Programming? Why Haskell?

Table of Contents

Goals of Real-World Haskell
The Nature of Functional Programming
Features of Haskell
Strong Typing and Type Inference
Laziness
Compiled or Interpreted
Purity
Modularity
Expressiveness
Composability
Robustness and Correctness
Things Haskell Doesn't Have (Or Need)
Mutable Variables
Looping with for or while
Haskell Environment
Helpful Resources

FIXME

Goals of Real-World Haskell

FIXME: goals of this book. The emphasis will be practical: on using FP and Haskell to design, write, and fix real programs. The audience is people who can already program. There will be plenty of examples and exercises.

As a new Haskell programmer, you'll inevitably end up writing quite a bit of code by hand for which you could have used a library function or programming technique, had you but known of its existence. You'll also run into instances where a cherished feature of another language isn't available; or a library function you just know ought to be there isn't; or occasionally something will be put together in such a way that you know it could have been improved upon. If you accept the inevitability of the occasional surprise, difficulty, and shortcoming, you'll have much more fun learning Haskell than if you step in expecting perfection, only to trip up within a few days or weeks of getting started.

The Nature of Functional Programming

FIXME

Features of Haskell

FIXME

FIXME: roots in research

FIXME: perception that it's not practical; this book will refute

Strong Typing and Type Inference

FIXME

Laziness

FIXME

Compiled or Interpreted

FIXME

Purity

FIXME

Modularity

FIXME

Expressiveness

FIXME

Composability

FIXME

Robustness and Correctness

FIXME

Things Haskell Doesn't Have (Or Need)

Mutable Variables

In a language such as C, you might see a statement such as x = x * 5 + y. This statement modifies the place in memory where x is stored and changes it to the result of the computation. Many, many other languages work the same way. For instance, a Python programmer might say mylist[5] = 10, which will set the value of the fifth element in mylist to 10.

In Haskell, all data is immutable -- it cannot be modified. If you need to modify an element of a list, you'll get a copy of the original list returned -- except for the one changed element. Then you will probably ignore the original list.

You might start to think that this could be slow to execute. That turns out not to be the case, as the Haskell compiler can optimize this sort of usage quite well.

It also turns out to be a powerful way to code: it makes it easy to "chain" functions together, the result of one being taken as input to another. POSIX programmers can think of this as similar to pipes in the shell.

There's another benefit of this: a lack of side-effects. A common source of bugs in many languages is calling a function that does something unexpected: modifies a global or a class variable, for instance. Later code then could behave in unexpected ways.

Some languages have partial immutability. For instance, strings are immutable in Java; if you want to add something to a string in Java, you combine two strings and the result is a new string -- not a modification of an existing string. Haskell takes immutability much farther. The only exception in Haskell deals with I/O, which is encapsulated in a special way; this will be discussed later.

Looping with for or while

Chances are that most languages you've used before have the notion of for or while. These tools are often used for performing actions a fixed number of times, for doing something over and over until some state changes, or for simply repeating infinitely until the program is killed.

Haskell has no for or while. That's not an oversight; Haskell doesn't have for or while because Haskell doesn't need them.

Let's consider a simple program to output the numbers from 1 to 10 on the screen. A C programmer might work this way:

#include <stdio.h>

void main(void) {
    int i;
    for (i = 1; i <= 10; i++) {
        printf("%d\n", i);
    }
}

      
#include <stdio.h>

void main(void) {
    int i;
    for (i = 1; i <= 10; i++) {
        printf("%d\n", i);
    }
}

      

This assigns the value 1 to i on the first time, then modifies that place in memory each time through, incrementing i until it reaches 10.

A Haskell programmer could simply say:

main = mapM_ print [1..10]main = mapM_ print [1..10]

The [1..10] generates an lazy list of numbers from 1 to 10. Each element will be created only when demanded. You could just as easily say [1..1000000] and you'll use no more memory.

The call to mapM_ takes an I/O function and runs it once for each element passed in. So we never need to directly modify memory, yet we can express the entire operation more compactly than in C.

A Haskell programmer could also express this without using mapM_ like this:

main = printit 1
printit 11 = return ()
printit x = do print x
               printit (x + 1)main = printit 1
printit 11 = return ()
printit x = do print x
               printit (x + 1)

This function uses recursion and pattern matching to achieve the result. You'll learn more about these techniques in the next few chapters in the book.

While Haskell's approach may seem foreign at first, we think that you'll grow to appreciate its speed and robustness as you learn about it. You'll see why Haskell doesn't have loops because loops would be less useful!

Haskell Environment

FIXME: Mention the Haskell environment that the book assumes (GHC 6.6+). Describe how to obtain and install it. Refer to alternative Haskell implementations (Hugs), but leave any detail to an appendix.

Helpful Resources

FIXME: Provide pointers to long-lived web sites, mailing lists, and IRC channels for help and social interaction with other Haskell people.

Want to stay up to date? Subscribe to the comment feed for this chapter, or the entire book.

Copyright 2007 Bryan O'Sullivan, Don Stewart, and John Goerzen. This work is licensed under a Creative Commons Attribution-Noncommercial 3.0 License. Icons by Paul Davey aka Mattahan.