# Learnings from playing with FizzBuzz for 3 days

As I wrote in a previous post1, I've been playing with Coding Katas to practice my TDD/Object-Oriented Design/Functional Programming skills.

And I write several solutions for a very simple Kata (`FizzBuzz`) in 3 days, here is what I got:

## Elixir: Data transformation pipeline

This is my Elixir solution for `FizzBuzz`:

```defmodule FizzBuzz do
def convert(number) do
""
|> maybe_concat(rem(number, 3) == 0, "Fizz")
|> maybe_concat(rem(number, 5) == 0, "Buzz")
|> fallback_if_empty(to_string(number))
end

defp maybe_concat(result, true, sound), do: result <> sound
defp maybe_concat(result, false, _sound), do: result

defp fallback_if_empty("", sound), do: sound
defp fallback_if_empty(result, _sound), do: result
end
```

Actually, this is my last attempt for `FizzBuzz` problem. I put it at the first because it's so simple and it literally blew my mind2.

And I think this solution also is a great example for explaining Elixir's core: Data Transformation.

As Dave Thomas said in Programming Elixir:

1. The goal of Elixir is data-transforming.

`FizzBuzz.convert/1` is just converting a string (`""`) into another string (`"Fizz"` or `""`), and another string , and so on.

2. `|>` operator makes data transformations explicit.

All these transformations were put together using the "pipe operator" (`|>`), which is the perfect match for data-transformation: data pipes in, new data pipes out.

3. Elixir code tries to be declarative, not imperative

Finally, if we look at the private methods, they are all declarative:

1. First, do pattern matching on the inputs
2. Then, based on the inputs value, generate some new data as the output

In Ruby, I always find myself to push the logic out of the code and into the data, something like:

```SOUNDS = {
3: 'Fizz',
5: 'Buzz'
}

def sound(factor)
SOUNDS[factor]
end
```

But with pattern matching, I can do this directly in the function declaration level and don't need to do this by myself anymore. And I find that I use Map in Elixir way less than I would use Hash in Ruby.

(And I'm also curious if it's still necessary to do that in Elixir. Please leave your thoughts in the comment.)

If we think a little bit further, in Ruby, we often initialize different classes based on the input and provides different behavior by leveraging the message dispatching (I call this ```Class Level Dispatch```).

But with pattern matching, we can send messages to different methods based on the input value (I call this ```Method Level Dispatch```).

Apparently, `Method Level Dispatch` has smaller granularity than `Class Level Dispatch`, so that we can write shorter code with it because we can push more message dispatching work to the programming language itself3.

## Ruby: Data Transformation by Hand

Of course, we can implement the same algorithm in Ruby:

```class FizzBuzz
def convert(number)
result = ""
result = maybe_concate(result, number % 3 == 0, "Fizz")
result = maybe_concate(result, number % 5 == 0, "Buzz")
result = fallback_if_empty(result, number.to_s)
result
end

def maybe_concate(result, concate?, sound)
if concate?
result <> sound
else
result
end
end

def fallback_if_empty(result, fallback)
if result.empty?
fallback
else
result
end
end
end
```

But it's not as clear as the Elixir solution:

1. Ruby doesn't have Pattern Matching yet4. So we need to handle different execution paths by conditional statements.
2. Ruby doesn't have the pipe operator. So we need a temporary variable to manually manage this state.

## Ruby: Chain of Responsibility

I also wrote a more complex solution in Ruby. (Because I want to try the Chain of Responsibility pattern and `FizzBuzz` seems to be a good fit.)

• `SoundsChain`

```class SoundsChain
def initialize(sound, fallback)
@sound = sound
@fallback = fallback
end

def for(number)
if sound.convertable?
sound.for(number)
else
fallback.for(number)
end
end

private

attr_reader :sound
end
```
• `ConcatenatableSound`

```class ConcatenatableSound
def initialize(sounds)
@sounds = sounds
end

def convertable?(number)
sounds.any? { |sound| sound.convertable?(number) }
end

def for(number)
sounds(number).join
end

private

attr_reader :sounds

def sounds(number)
sounds.map { |sound| sound.for(number) }
end
end
```
• `FactorSound`

```class FactorSound
def initialize(factor, sound)
@factor = factor
@sound = sound
end

def convertable?(number)
number % sound == 0
end

def for(number)
if convertable?(number)
sound
else
''
end
end

private

attr_reader :sound
end
```
• `StringSound`

```class StringSound
def convertable?(_number)
true
end

def for(number)
number.to_s
end
end
```

We have 2 chains here:

`SoundsChain`
It will return the sound if this number is convertable by current sound, otherwise it will ask fallback sound to convert the number.
`ConcatenatableSound`
This class is not strictly a Chain of Responsibility, since the `#for` method is concatenating all the converted results in this chain.

It is a complex solution. But we can see a absolutely clean interface here:

`convertable?`
Test if this `number` can be convert by this object.
`for`
Return the converted sound for this number if possible.

## Summary

`FizzBuzz` is a pretty simple problem that can be solved in many different ways, like:

1. Pass in `Proc` as `#for` and `#convertable?`
2. Use instance variable as the internal state to convert sounds
3. etc.

I'm not saying that Elixir's solution is better than Ruby's solution. It's just that `FizzBuzz` is a perfect data transforming question that's a perfect fit for Elixir.

I'm also not saying that Chain of Responsibility is a better solution for `FizzBuzz`. We can see that it's more complex and needs more lines of code to implement.

It's pretty interesting to do coding katas in these ways to explore different solutions. Give it a try and maybe you can find more useful things from a simple problem.