Function composition in Ruby

Matthew Glover
1 min readDec 14, 2017

--

We’re now deep into the festive period, and I’ve started to be filled with the Christmas spirit. Perhaps as a result of which, I’ve been playing around with the idea of writing functional code in Ruby… Not because I think this is a good idea, or “the future”, but just because.

In that spirit, I decided to see if I could implement a compose function in Ruby. I wanted compose to be a variadic function, which takes one or more unary (single-argument) functions and returns a new function which is the composition of the supplied functions.

For example, given two lambda functions:

addOne = { lambda { |n| n + 1 } }
timesTwo = { lambda { |n| n * 2 } }

I want to have a compose function, such that:

compose(addOne, timesTwo).call(n) == addOne.call(timesTwo.call(n))

Ignoring the requirement for compose to be variadic function, a solution for two functions might be:

def compose2(f, g)
lambda { |x| f.call(g.call(x)) }
end

The solution for compose to be three functions might then be:

def compose3(f, g, h)
lambda { |x| f.call(g.call(h.call(x))) }
end

This reveals an interesting pattern, because another way of defining this might be:

def compose3(f, g, h)
compose2(compose2(f, g), h)
end

This pattern can then be more generally expressed with a reducer:

def compose(*fns)
fns.reduce { |f, g| lambda { |x| f.call(g.call(x)) } }
end

Which now gives us our variadic compose function in Ruby. Maybe not very useful, but still quite interesting!

--

--