Pragmatism vs. Moral Purity


#1

I want to create a list with many repeated entries. The input consists of lists of index numbers and the value to be placed at the corresponding index. Thus, this input:

[([0,1,3,6], "ant"), ([2], "bee"), ([4,5], "cat")]

would produce this output:

["ant", "ant", "bee", "ant", "cat", "cat", "ant"]

The pragmatist in me says to make the output an array and use Js.Array.spliceInPlace, which makes the task fairly simple. The idealist in me says it is more “morally pure” to use lists and and a more purely functional approach (fold, etc.), but the task becomes much more difficult.

I’m wondering what you all think.


#2

You could have the best of both worlds: build up an array internally and return an immutable list. You could have a function with the following signature:

let repeatEntries: list((list(int), string)) => list(string)

Internally, you could do the following:

  • Figure out the maximum index and allocate an array of length maxIndex + 1
  • Iterate through the input list and place each entry in its correct position in the array using List.iter and Array.set (or the array index operator)
  • Return an output list using Array.to_list

The reason I’m recommending this imperative approach is because all the mutation is happening internally within your single function call, and is not observable from the outside world. Hence, it is still referentially transparent, and perfectly idiomatic functional programming.