Functional programming and Haskell

Tags:

I’ve been learning some Haskell for fun. Haskell is a functional language, so it’s quite different from other languages I know like PHP or C#.

One of the main “ideas” of functional programming is immutability – in other words, you can’t change the value of a variable after you’ve defined it. How do you deal with this?

Also, Haskell has no loops, like for or while, and a very weird syntax. So is it any good?

Functional programming

If you want a way to make programming just plain difficult again, you can start learning a functional language! (or use C ;) )

It can initially be a quite big challenge to adjust the way you think into how you need to think when working with Haskell or some other functional language.

  • You can’t modify variables
  • You don’t have loops
  • The way you structure code is weird
  • etc.

But despite this, I think it’s an interesting and refreshing way to write code. Sometimes it can help you think about your code in a new way even when not using a functional language.

Immutable variables may initially seem like a problem. How do you calculate anything if you can’t modify the variable? You use recursion.

No loop constructs? You use recursion.

For example, if you want to calculate a sum of the values in a list, you would do something like this:

//this example is in PHP to make it easier to understand if you don't know Haskell
function sum($array) {
  if(count($array) == 0)
    return 0;
  else
    return $array[0] + sum( array_slice($array, 1) );
}
 
$arr = array(3, 3, 3);
$sum = sum($arr);
//$sum=9

As you can see from the example, no looping was used, and no variable was modified. The function just returns 0 if the array is empty, or takes the first index of the array, and sums it with the result of passing the rest of the array except the first, to sum again.

Let’s take a look at how it would look in Haskell:

sum (x:xs) = x + sum xs
sum [] = 0

The syntax above may seem a little odd, but it’s much shorter than the PHP version, and if you understand the syntax, easier to read too. I’ll explain the syntax a bit more in depth a bit later in the post.

Recursion is a pretty typical answer to the differences. You may have used recursive algorithms in some other language to for example parse a tree, but it’s probably not a very common way to write algorithms in other languages.

Lists are another common way to work with things in Haskell. There are some built in functions that can be used to process a list using another function, so you may not need to write recursive functions for every task, as they can often be simplified with the built in ones.

For example, there’s already a sum function, so we wouldn’t actually have had to write one, but it served as a nice example.

You can read more about functional programming at Wikipedia

Syntax

As shown in the example earlier, the syntax in Haskell is quite different. Many other functional languages share this style of syntax as well.

Learning the syntax is probably one of the biggest things in learning a functional programming language, and to people who aren’t familiar with it, it definitely looks weird and confusing.

However, the syntax is actually quite easy to read, and makes much sense, after you learn it!

I’m not going to teach you all of Haskell syntax, but I’ll show you few interesting examples of it. If you actually want to learn Haskell, the book Real World Haskell is very good, and you can read it online for free.

Let’s take a look at our earlier sum-function:

sum (x:xs) = x + sum xs
sum [] = 0
 
list = [3, 3, 3]
result = sum list

You might already guess something from this, but why is sum being defined twice? Also, what is x:xs?

To understand the example, you must first know that in Haskell, you don’t use parenthesis when passing parameters to functions. So the first line is calling sum and passing xs as its parameter.

The reason we have sum “defined twice” is that we are using a feature of Haskell: pattern matching.

The first line means that the function takes one parameter, as its in parentheses, which in this case is a list. The x:xs means that we want to take the first item from the list to a variable called x, and put the rest of the list to xs. In the case of a list, we define the result to be x + sum xs, which should be fairly obvious now.

The second line means that in case the parameter is an empty list, the function will simply return 0 (the function “equals” zero). This is similar to our if-structure in the PHP example: if the parameter is an empty list, the function’s result will be 0.

So when the function runs, it first “matches” the first line as we pass a list with three items. The function will call itself again, and the first one will still match, as the list has two more items. It will match once more, and at that point the list will be empty, because we always took the first item off the list into x. When the function calls itself with an empty list, the second line will match, and the function will not call itself anymore, ending the loop.

This may seem a bit odd at first, but it actually has some benefits:

  • You can immediately see what kind of results the function can return
  • You can immediately see what types of input result in what kind of processing

If we read the PHP example, we must read the whole function definition to see what it does. The Haskell function is more clear in the way as you can see the definition an result immediately.

Let’s look at another bit more complex example to see some more Haskell features: Guards and where:

-- this returns a textual representation of a number
-- useful for printing stuff like "one car" or "10 cars"
amountStr x
  | x < 6     = strs !! (x - 1)
  | otherwise = show x
  where strs = ["No", "One", "Two", "Three", "Four", "Five"]

The first two lines are comments, which should explain the basic idea of this function. However, there’s more odd syntax!

This time there are pipe symbols and a comparison etc..

Let’s look at the first line of the function: This is a guard. If the parameter x is smaller than 6, then the result of the function will be the one after the equals sign on this line. The code in this one takes the strs, and returns the x – 1 th item from it – foo !! x is basically the same as $foo[x] notation in PHP.

On the second line of the func, we have another guard: This one has just the word “otherwise” – which is simply a synonym for the boolean value True. In case our first guard does not evaluate to true, the otherwise guard will always evaluate to true. The code in this simply “shows” x – show is a function which will attempt to convert any value passed to it to a string.

The last thing in the function is a where-block: You can use a where-block to define variables in the scope of the function. It’s good for defining things like the strs list, as we won’t need to litter the main body of the function with the definitions of variables, and if we need to find what some variable is, we have an easy place to find it.

So is this actually useful for something?

Is it? I’m not sure. I definitely enjoyed learning about all this, though! I really like the way Haskell works, and there’s a lot of libraries available so you can interact with things like databases etc., so it isn’t a useless language either.

We may see a rise in functional languages some day: Due to the side-effect free nature of functions in them, they are easier to run in multiple threads without the programmer having to write any concurrency-related code – the compiler can optimize it to multithread for you. Seeing how CPUs keep getting more and more cores, and the fact that writing bug-free threading code can be tricky, this may be a time for functional languages.

There’s also a language called F#, which has a similar syntax as Haskell, but it’s based on OCaml. As you may have guessed from the name, it’s a language which uses the .NET Framework. This means you can very easily utilize functional programming to write Windows apps or pretty much anything, as you can fully use everything available in the large .NET Framework.