Stream: beginners

Topic: FizzBuzz example


view this post on Zulip Dimitrios Piliouras (Jun 02 2024 at 20:35):

I was just glossing over some examples here, and I couldn't help but notice, how 'boring' the fizz-buzz example is. The most elegant/expressive/concise implementation I have ever seen is the one below. Does anyone know if such level of elegance and purity can be achieved with Roc? I do understand that Roc doesn't have lazy-sequences, but at the same time I don't mean translate this code line by line - perhaps the core idea can be translated in Roc w/o laziness...
Screenshot-from-2024-06-02-21-28-04.png

view this post on Zulip Brendan Hansknecht (Jun 02 2024 at 20:41):

Personally, I think I would just go with something simple:

fizzbuzz = \i ->
    when (i % 3, i % 5) is
        (0, 0) -> "FizzBuzz"
        (0, _) -> "Fizz"
        (_, 0) -> "Buzz"
        _ -> Num.toStr i

view this post on Zulip Dimitrios Piliouras (Jun 02 2024 at 20:43):

ok that is nicer, but you're still doing two modulo operations, 4 ifs, and writing "FizzBuzz" by hand

view this post on Zulip Brendan Hansknecht (Jun 02 2024 at 20:51):

A more direct translation would be this:

a = ["Fizz", "", ""]
b = ["Buzz", "", "", "", ""]

getWrap = \list, i ->
    when List.get list (i % List.len list) is
        Ok v -> v
        Err _ -> crash "invalid"

fizzbuzz = \i ->
    when Str.concat (getWrap a i) (getWrap b i) is
        "" -> Num.toStr i
        x -> x

view this post on Zulip Dimitrios Piliouras (Jun 02 2024 at 20:52):

ok now we're talking

view this post on Zulip Dimitrios Piliouras (Jun 02 2024 at 20:52):

wow this is great

view this post on Zulip Dimitrios Piliouras (Jun 02 2024 at 20:52):

oh I see - you've basically made up this 'gap-cycle' yourself

view this post on Zulip Dimitrios Piliouras (Jun 02 2024 at 20:53):

i mean there may be a better way to do this, but the core function certainly reads great

view this post on Zulip Dimitrios Piliouras (Jun 02 2024 at 20:54):

thanks again!

view this post on Zulip Dimitrios Piliouras (Jun 02 2024 at 20:58):

but wait - getWrap can crash the program?

view this post on Zulip Brendan Hansknecht (Jun 02 2024 at 20:58):

Only is the list is size 0

view this post on Zulip Brendan Hansknecht (Jun 02 2024 at 20:59):

So in this case it is impossible

view this post on Zulip Dimitrios Piliouras (Jun 02 2024 at 20:59):

shouldn't the Err case return the empty string?

view this post on Zulip Dimitrios Piliouras (Jun 02 2024 at 21:00):

oooo i see

view this post on Zulip Dimitrios Piliouras (Jun 02 2024 at 21:00):

right right

view this post on Zulip Dimitrios Piliouras (Jun 02 2024 at 21:05):

so your second version is essentially branch-less - the only conditional is comparing the empty String with the result of Str.concat, which should be super cheap.

view this post on Zulip Dimitrios Piliouras (Jun 02 2024 at 21:07):

and List.len I assume is a constant-time operation

view this post on Zulip Brendan Hansknecht (Jun 02 2024 at 21:08):

Yep


Last updated: Jul 05 2025 at 12:14 UTC