Yesterday I saw an interesting presentation from Devoxx by Dierk König called Frege, a Haskell for the JVM. I think he did quite a good job of bringing forth some of the benefits of functional programming and pure functions. Especially in his last example where he was demonstrating his way of solving the FizzBuzz problem in Frege (which is Haskell-like language on top of the JVM). The FizzBuzz problem can be summarized like this:
Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.
In Java a (naive) solution might look like this:
public class FizzBuzz{
public static void main(String[] args){
for(int i= 1; i <= 100; i++){
if(i % 15 == 0){
System.out.println("FizzBuzz");
}else if(i % 3 == 0){
System.out.println("Fizz");
}else if(i % 5 == 0){
System.out.println("Buzz");
}else{
System.out.println(i);
}
}
}
}
There are several problems with this approach. For example it's hard to add additional requirements (for example if we want to print "Devoxx" for every multiple of 7), the ordering of the if statements are important, cyclomatic complexity is quite high and there's nesting etc etc. The Frege solution presented by Dierk looks like this:
fizzes = cycle ["", "", "fizz"]
buzzes = cycle ["", "", "", "", "buzz"]
pattern = zipWith (++) fizzes buzzes
numbers = map show [1..]
fizzbuzz = zipWith max pattern numbers
main _ = for (take 100 fizzbuzz) println
If you have a basic understanding of Frege/Haskell this is a nicer solution indeed (please see the presentation or have a look at Dierks e-book (chapter 8)). For a Java developer not used to this style of programming it might seem that this solution is more complex but in fact it's the other way around (remember that simple is not (necessarily) easy!). Here are some figures from Dierks talk (he talks about it at 42:05):
Anyway after seeing his presentation I wanted to port this solution to Clojure to see how close they would resemble each other. This is my attempt:
(defn fizzbuzz [length]
(let [fizzes (cycle ["" "" "fizz"])
buzzes (cycle ["" "" "" "" "buzz"])
pattern (map str fizzes buzzes)
numbers (iterate inc 1)
fizzbuzz (map #(if (.isEmpty %1) %2 %1) pattern numbers)]
(doseq [m (take length fizzbuzz)]
(println m))))
This function will print the fizzbuzz sequence up until length length
. As you can (hopefully) see it looks quite similar to the Frege implementation. This is also one of the things I like with functional programming. Once you learn the basic concepts and the core functions its quite easy to switch between different languages.
35 thoughts on “Porting Frege FizzBuzz solution to Clojure”
I don’t think the title of your article matches the content lol. Just kidding, mainly because I had some doubts after reading the article.
симулятор кота читы https://apk-smart.com/igry/189-chity-simuljator-kota-vzlomannaja.html симулятор кота читы
P.S Live ID: K89Io9blWX1UfZWv3ajv
P.S.S Программы и игры для Андроид телефона Программы и игры для Андроид телефона Программы и игры для Андроид телефона 9d93ca6
rhAP3EC34xB
Thank you for your sharing. I am worried that I lack creative ideas. It is your article that makes me full of hope. Thank you. But, I have a question, can you help me?
rcERLtEbkNe
gcj8mHwtJPc
7ENnOprPfBn
oF6zLe1pKru
ILg7PsK3Pbj
PlqunggrQeP
B8FSXS8TeS7
4P8giiIIC3e
DcmR9pMkQep
zvQlHfwfZOg
9BiJnQMqYdh
JIfW4802tza
TJQcBtTaa0X
ApD5RxABrma
j1PCXxseocx
5jleeMAv8Sm
NpL27pQlse1
LVP0l2EDjES
efJUQ8Xqg5H
IdDgbWENUgy
3Eyq6Sa32WD
B9jdinXvN7z
1I9925ZindW
CXbneN8Nldl
S5kdA9JJI0j
EOwAyTdCVuZ
wEngiPWcfav
VbQkR3sfQCV
2b57nPC3SFz
Y9Zuqm8j1cT
UiqRiQjiwwz