# Functions as Data

Programming languages have evolved largely through a series of abstractions; these abstractions mostly deal with control (e.g. functions) or data. In the post, Houses, Arrays and Higher Order Functions, we have focused on the use of functions as control elements and have delved into the concept of higher order functions. Today we will revisit functions and focus on their use as data elements. Using functions to represent data might seem pretty counter intuitive at first but this blurred line between functions as control elements and functions as data elements is a powerful concept.

# Sets

In order to illustrate how functions can be used as data elements we will create a Set library with the following operations: `union`

, `intersection`

and `difference`

. We will define a set using the characteristic function `T -> Boolean`

i.e. a function which takes an element `T`

as input and return a `true`

or `false`

depending on whether the element is contained within the set. Using classic OOP we can define a set as follows:

```
class Set<T>(vararg values: T) {
var elements: List<T> = values.toList()
fun contains(element:T): Boolean = this.elements.contains(element)
}
```

In this case a set is defined as a class with a generic type `T`

, we will use the underlying list data structure `elements`

to implement the `contains`

function. We can use the OOP representation as follows:

```
val s1 = Set(1)
val s2 = Set(2, 3, 4)
```

Using functions as data elements we would implement a Set as follows:

```
fun <T>setOf(element: T): (T) -> Boolean = { test -> element!!.equals(test) }
fun <T>contains(set: (T)->Boolean, element: T): Boolean = set(element)
```

The function `setOf`

is a *constructor* function (as defined by SICP) which takes in an `element`

and returns a higher order functions that implements the characteristic function `(T) -> Boolean`

. `contains`

just delegates the test to the `setOf`

higher order function by calling `set(element)`

. Some observant readers might have noticed that the class `Set`

can ingest a number of values whilst the `setOf`

function can only ingest one value. Using the `union`

operator (defined further on) we can extends the `setOf`

function to accept a variable number of elements `T`

.

```
fun <T>setOf(vararg elements: T): (T) -> Boolean {
return elements.map { setOf(it) } .reduce { s, t -> union(s, t) }
}
```

Using the `setOf`

function we can define the set `s1`

and `s2`

as follows:

```
val s1 = setOf(1)
val s2 = setOf(2, 3, 4)
```

Note that even though the representation is completely different the end user consuming either library will not be exposed to the underlying details of our implementations (OOP vs Functions). To an end user (except for minor syntactic differences) these two Sets are not different from each another.

# Union

Now that we have a means of representing a set, let us implement `union`

in both representations. In the OOP approach we would implement union as follows:

```
class Set<T>(vararg values: T) {
fun union(other:Set<T>): Set<T> {
val unionSet = Set<T>()
val elements = ArrayList(this.elements)
elements.addAll(other.elements.filter { x -> !this.elements.contains(x) })
unionSet.elements = elements
return unionSet
}
...
}
```

In this case we are using the backing data stucture `elements`

to keep track of what is *in* the set. We can test this implementation as follows:

```
val s1 = Set(1)
val s2 = Set(2, 3, 4)
println(s1.union(s2).contains(1)) // -> true
println(s1.union(s2).contains(2)) // -> true
println(s1.union(s2).contains(3)) // -> true
println(s1.union(s2).contains(4)) // -> true
println(s1.union(s2).contains(5)) // -> false
println(s1.union(s2).contains(0)) // -> false
```

Using functions we get a much more pure definition (mathematically speaking):

```
fun <T>union(s1: (T)->Boolean, s2: (T)->Boolean): (T)->Boolean =
{element -> s1(element) || s2(element) }
```

An `element`

is contained in the union of set `s1`

and `s2`

if the `element`

is either in set `s1`

or `s2`

. This is clearly represented by the line `element -> s1(element) || s2(element)`

. Don't be fooled by the fact that Kotlin does not support structural types, had the language supported structural types our definition would be a bit more concise:

```
fun <T>union(s1: Set<T>, s2: Set<T>):Set<T> =
{element -> s1(element) || s2(element) }
```

Needless to say this is just semantic sugar; regular functions (with milk) will do just fine! One would use the union operator as follows:

```
val s1 = setOf(1)
val s2 = setOf(2, 3, 4)
println(contains(union(s1, s2), 1)) // -> true
println(contains(union(s1, s2), 2)) // -> true
println(contains(union(s1, s2), 3)) // -> true
println(contains(union(s1, s2), 4)) // -> true
println(contains(union(s1, s2), 5)) // -> false
println(contains(union(s1, s2), 0)) // -> false
```

Note again that the usage is very similar and an end user would find it hard to believe that the Set is implemented using functions.

# Intersection

Having defined `union`

, `intersection`

will only be one synaptic leap away. Let's start off with the OOP version.

```
class Set<T>(vararg values: T) {
fun intersection(other:Set<T>): Set<T> {
val intersectionSet= Set<T>()
val elements = ArrayList<T>()
elements.addAll(this.elements.filter { x -> other.contains(x) })
intersectionSet.elements = elements
return intersectionSet
}
...
}
```

One would use the definition above as follows:

```
val s3 = Set(1, 2)
val s4 = Set(2, 3, 4)
println(s3.intersection(s4).contains(1)) // -> false
println(s3.intersection(s4).contains(2)) // -> true
println(s3.intersection(s4).contains(3)) // -> false
println(s3.intersection(s4).contains(4)) // -> false
println(s3.intersection(s4).contains(5)) // -> false
println(s3.intersection(s4).contains(0)) // -> false
```

Using functions, we would represent the intersection function as:

```
fun <T>intersection(s1: (T)->Boolean, s2: (T)->Boolean): (T)->Boolean =
{ element-> s1(element) && s2(element) }
```

Note how close this function is to the original mathematical definition; an `element`

is contained in the intersection of Set `s1`

and `s2`

if the `element`

is contained in set `s1`

and set `s2`

, hence:

```
element -> s1(element) && s2(element)
```

One would use the above definition as follows:

```
val s3 = setOf(1, 2)
val s4 = setOf(2, 3, 4)
println(contains(intersection(s3, s4), 1)) // -> false
println(contains(intersection(s3, s4), 2)) // -> true
println(contains(intersection(s3, s4), 3)) // -> false
println(contains(intersection(s3, s4), 4)) // -> false
println(contains(intersection(s3, s4), 5)) // -> false
println(contains(intersection(s3, s4), 0)) // -> false
```

# Difference

For completeness let us now implement `difference`

in both representations. In the OOP approach we would implement difference as follows:

```
class Set<T>(vararg values: T) {
fun difference(other:Set<T>): Set<T> {
val differenceSet= Set<T>()
val elements = ArrayList<T>()
elements.addAll(this.elements.filter { x -> !other.contains(x) })
differenceSet.elements = elements
return differenceSet
}
...
}
```

Using functions we can implement this using:

```
fun <T>difference(s1: (T)->Boolean, s2: (T)->Boolean): (T)->Boolean =
{element-> s1(element) && !s2(element) }
```

# Set of multiple elements

Before we conclude I would like to give an intuition for the function

```
fun <T>setOf(vararg elements: T): (T) -> Boolean {
return elements.map { setOf(it) } .reduce { s, t -> union(s, t) }
}
```

Specifically how we used `map`

and `reduce`

to create a *characteristic function* which accepts multiple elements as follows:

```
val s3 = setOf(2, 3, 4, 7)
```

What `elements.map { setOf(it) }`

does is map all `elements`

to a characteristic function, hence 2 becomes:

```
test -> 2.equals(test)
```

3 becomes:

```
test -> 3.equals(test)
```

and so on.

The `reduce`

function will combine the characteristic functions as follows:

```
union (
union(
union(
{test -> 2.equals(test)},
{test -> 3.equals(test)}
),
{test -> 4.equals(test)}
),
{test -> 7.equals(test)}
)
```

Each `union`

function creates a new characteristic function combining the underlying two characteristic functions. For e.g.

```
union(
{test -> 2.equals(test)},
{test -> 3.equals(test)}
)
```

would create the following characteristic function:

```
{test ->
{test1 -> 2.equals(test1)}(test) ||
{test2 -> 3.equals(test2)}(test)
}
```

If we want to test whether 2 is in the set union, we would reduce the characteristic function as follows:

```
union({test -> 2.equals(test)}, {test -> 3.equals(test)})(2)
{test ->
{test1 -> 2.equals(test1)}(test) || // 2 here is the element in the set s1
{test2 -> 3.equals(test2)}(test) // 3 here is the element in the set s2
}(2) // 2 is the value to test.
```

Replace all occurrences of `test`

with the value 2, we obtain:

```
{test1 -> 2.equals(test1)}(2) || {test2 -> 3.equals(test2)}(2)
```

Replace all occurrences of `test1`

and `test2`

with the value 2, we obtain:

```
2.equals(2) || 3.equals(2)
true
```

Hence the characteristic function for the set union between `s1`

and `s2`

when applied to 2 has reduced to true, which is correct.

# Conclusion

In this post we have looked at how we can use functions as data elements. Using functions as a data representation might feel unnatural at first but this blurred boundary between functions as elements of control and functions as elements of data is quite powerful. I really hope that you find this technique useful. Stay safe and keep hacking!