PAPER 2 - ⇑ Fundamentals of functional programming ⇑

What is functional programming Basics of functional programming →


Functional programming is a declarative programming paradigm, where programs are written as mathematical functions whose order of execution is not solely defined by the programmer. These mathematical functions produce consistent outputs solely dependent on the inputs. Functions can be constructed out of other functions, or call themselves recursively. Functional programming is different from the imperative programming paradigm in several ways:

The outputs of functions only depend on the inputs, and not the changing state of a program, functional programming is stateless. For example, the python program below calls the same function addNumbers twice with the same parameters 2,2, but different values are returned because the state of the program (here simulated by the variable c) changes. This wouldn't happen in a functional programming language, as whenever you call a function with the same arguments the same output would be produced.

Python example Haskell example
def addNumbers (a, b):
   return a + b + c

...
print(addNumbers(2,2)) # prints 8
...
print(addNumbers(2,2)) # prints 6
addNumbers a b c = a + b + c
...
addNumbers 2 2 2  --returns 6
...
addNumbers 2 2 2  --returns 6
not functional programming as addNumbers uses
the global variable c
functional programming, the value returned by
addNumbers is only dependent on the inputs


Functional programming languages avoid side effects. A side effect is where a function modifies something outside its local environment. In the example below the function fudgeNumbers changes a global variable g when it is run.


Python example Haskell example
g = 0

def fudgeNumbers (a, b):
   global g
   g = a + (2 * b)
   return a * b
print(g) # prints 0
print(fudgeNumbers(2,2)) # prints 4
print(g) # prints 6
g = 0
fudgeNumbers a b = a + b
g --returns 0
fudgeNumbers 2 2 --returns 4
g --returns 0
not functional programming as fudgeNumbers changes
the value of a global variable g when run

functional programming, fudgeNumbers
only returns a value, it doesn't change
anything outside its scope

Functional programming also avoids using variables that change at runtime, data structures are considered to be immutable.

Python example Haskell example
a = 2
b = 5
c = a + b
a = 6
a = 2
b = 5
c = a + b
not functional programming as it
changes the value of a at runtime

functional programming, variables are only declared once

Functional programming paradigm - computation is the evaluation of mathematical functions that avoid side effects and changing variables at runtime


Benefits of the functional programming paradigm include:

  • supporting the decomposition and abstraction of computing problems into functions that are made up of other functions which are made of other functions and so on.
  • easier to read and understand code.
  • easier to debug code as each function can be tested separately and does not rely on the state of the machine.
  • lending themselves to running parallel and concurrent progam execution, allowing functional programs to run on multi-processor systems.

Lisp was one of the first functional programming languages, being created in 1958. Several dialects of Lisp are still in common usage including Common Lisp and Scheme. Other functional programming languages include Erlang and Haskell. Whilst imperative programming languages are more commonly used than pure functional languages, it is possible to do functional programming with many modern languages. Other languages that support functional programming include Python, C#, F#, Java, Visual Basic .NET and JavaScript.

Scheme example code
 (defun factorial (n)
   (if (= n 0) 1
       (* n (factorial (- n 1)))))

Using Haskell for the first time

edit

The majority of the code examples in this chapter will be in Haskell. You can learn more about Haskell over at Learn You a Haskell for Great Good!. To execute the examples shown in this chapter you can download the open source Glasgow Haskell Compiler or GHC. Most examples can be written directly into the command line interface that the GHC gives you, below this is shown with the .> symbol. For example:

.> putStrLn "Hello World!"
Hello World!
.> 4 ^ 7
16328
.> [1..8]
[1,2,3,4,5,6,7,8]
.> round 7.8
8

Later examples might require you to write multiline programs, especially when you need to declare your own functions, to do this you need to open a text editor and save your Haskell file with the .hs extension. For example:

myFirstHaskell.hs
myFactorial :: (Integral a) => a -> a  
myFactorial 0 = 1
myFactorial n = n * factorial (n - 1)

We can then load this into the GHC by using the :l (load) command, followed by the file location and name.

.> :l myFirstHaskell.hs
[1 of 1] Compiling Main             ( myFirstHaskell.hs, interpreted )  
Ok, modules loaded: Main.

Now we can use the loaded function, myFactorial, from the command line:

.> myFactorial 4
24
Exercises: Funcational programming fundamentals

What is a functional programming language?

Answer:

A functional programming language is one where code has no side effects, the program execution is stateless and the outputs of functions only depend on the inputs.

Describe two of the benefits of using a functional programming language

Answer:

  • easier to debug
  • easier to read and understand
  • can run on parallel systems


Explain why this wouldn't be considered an example of a piece of functional programming?

...
def multiply (a):
   return a * b
...

Answer:

We don't know what value b will be at runtime so the multiply function will output different values depending on the state of the computer.