Functional programming notes: Functions

  2 mins read

In the previous posts, we took a look at how functions are the core pieces in functional programming languages. We talked about pure functions, referential transparency, side effects and recursion in the previous posts. In this post, we are going to explore some properties of functions and how we can use them in a functional programming language.

Function definition

A function is a black box that for a given input it gives you back always the same output. As we stated before a function does not have any side effects. A function accepts a set of input values; we call that the domain of a function. The output of a function is called codomain and the set of outputs is called the image of the function. We can decompose them like this:

f: A -> B

Where A is the domain and B is the codomain. For example, for the function f(x) = 2x we can decompose it as it follows:

domain-codomain-image

Where as we stated, A is the domain, B is the codomain and [2, 4, 6] is the image of the function.

Arity

Arity is the number of arguments that the function takes. We say that the arity of f(x: Int) is 1 or that is a unary function. Therefore, the arity of a function can be expressed with a number or the spring term. Unary, binary, ternary, etc… Are words that come from Latin, but mathematicians usually use Greek instead of Latin so usually they interchange those words for the same ones coming from Greek. We can say as well that the arity of a function is monadic, dyadic or triadic.

Function composition

Function composition is one of the bases of functional programming. The base premise of it is that if you have a function f = A->B and a function g = B->C you can create a 3rd function h = A->C which internally uses f and g to create that C, that is: h = g(f(x)). If we express it with mathematic terms we can say that h = f∘g readed as “h is equal to f after g” or what is the same: h = Cgf
An example of function composition is:

def intToString(i: Int) : String = i.toString
def stringToInt(s: String) : Int = s.toInt
val composedFunction = intToString _ compose stringToInt

We declared two functions intToString and stringToInt, when we compose them we create a 3rd function which accepts an string an returns an int. So if we call it: composedFunction("32") it returns "32" which is the result after convert that string to int and from that int to an String again. Notice that, to compose that functions we write first the last function, this time: intToString and then stringToInt. We can do the same without modify the order of the functions with the function andThen, this will be like this:

val composedFunction2 = stringToInt _ andThen intToString

This is the same and in my opinion less confusing.
Despite the scala syntax, I am using infix operators, is the same if we express it with parenthesis:

val composedFunction2 = (stringToInt(_)).andThen(intToString)

In this post, we reviewed some of the concepts that involve functions in functional programming and we’ve seen some examples on how to compose them. I hope it was not so dense 🙂

References

This books inspired me; I’ve been working with those for a while and are worth it: