Around IT in 256 seconds

#60: Haskell: purely functional and statically typed programming language

December 08, 2021 | 3 Minute Read

Haskell is a purely-functional programming language. It is also statically and strongly typed. Haskell takes these characteristics to the extreme. For example, doing any input/output is considered impure from a functional programming point of view. So in some books, a simple “Hello, world” example appears as late as in chapter… 9.

On the other hand, the type system is really powerful and clever. Sometimes it’s jokingly said that if your Haskell program compiles, it must be correct. This is somewhat true. The type system is so expressive and the compiler so strict that many potential bugs manifest as compilation errors. To give you an idea of how precise the types are: there is a search engine known as Hoogle. Like Google, but with H. In Hoogle you type a signature of a function you are looking for and it’ll find the appropriate library function.

For example, let’s say you ask for a function that takes a list. And returns a list of the same type. There are many functions like that, for example reverse or tail. However, if you also require that elements of that list must support ordering with each other… Well, in that case, you must be looking for a sort function. This is exactly what Hoogle suggests.

By the way, specifying that a given type support equality, ordering or turning itself into a string is supported via so-called type classes. Type classes are somewhat similar to interfaces in Java but much more powerful. For instance, you can define them externally and in multiple different ways for the same type.

OK, but this is just the beginning of Haskell awesomeness. Expressions in Haskell are evaluated lazily. This means you can work with theoretically infinite data structures. Also, some algorithms are much easier to implement when the runtime only evaluates as little as needed.

Being a functional programming language, Haskell supports higher-order functions and lambda expressions. In Haskell, it’s absolutely fine to “forget” about the last argument of a function. You won’t get a compilation error! It’s best explained with an example.

There’s a drop function that accepts an integer and a list. If you invoke drop 3 "foobar" it’ll return "bar". But what if you invoke drop 3 without a second argument? Congratulations, it works just fine! You just created another function that, when invoked on a list, drops the first 3 elements. You can name drop 3 expression as skipFirstThree and use it as an ordinary function. Oh, and Haskell has excellent type inference. It means the compiler is amazingly good at guessing what’s the signature of your newly created function.

One of the most surprising features of Haskell is the way it handles input/output. Every impure operation must be wrapped in an IO monad. Monads deserve an episode on their own, so let’s stop right here.

Haskell has many other interesting properties, like pattern matching and immutability. This language is most popular in academics and programming language research. However, there are some practical applications. For example, Facebook’s spam filter was famously written in Haskell. Also, John Carmack, one of the creators of legendary Wolfenstein 3D, rewrote that game years later in Haskell. Turns out, despite a very strict environment, it has a lot of benefits. Surprisingly, immutability in such a dynamic game actually helps!

That’s it, thanks for listening, bye!

More materials

Tags: functional-programming, haskell, monad, wolfenstein-3d

Be the first to listen to new episodes!

To get exclusive content: