Thinking Functionally

Julia is easily my favourite language but I still love playing with Haskell. In fact, I do believe that all the time I spent learning Haskell has actually made me a better programmer in Julia because it comes down to how someone thinks about problems.

In the first problem on Project Euler, we are asked to sum up every number below \(1000\) which is a multiple of \(3\) or \(5\).

In most imperative languages this type of problem would be solved in the following way using C syntax.

long sum = 0;
long upper_bound = 1000;

for (size_t i = 0; i < upper_bound; i++) {
	if (i % 3 == 0 || i % 5 == 0)
		sum += i;
}

printf("%l\n", sum);

The approach is different in functional languages because we generally are thinking about the problem in terms of sets and applying functions to those sets.

The way we would solve this problem mathematically would be to first define two sets. \(U\), containing all multiples of \(3\), and \(V\), containing all multiples of \(5\). We set an upper bound of \(1000\) and union \(U\) and \(V\),

\[ U \cup V = \{ x : x \equiv 0\ (\text{mod}\ 3) \wedge x \equiv 0\ (\text{mod}\ 5) \wedge x < 1000 \}\,.\]

Finally, we would sum over every element of \(U \cup V\) to yield our result,

\[ \sum_{i = 1}^n (U \cup V)_i \]

In Haskell, the syntax is very similar to the mathematical approach.

u = [3,6..999]
v = [5,10..999]
sum $ u `union` v

We could do something very similar in Julia as well.

union(Set(3:3:999), Set(5:5:999)) |> sum