# Please critique my FizzBuzz!

**URL:** <https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987>\
**Category:** General Usage\
**Created:** [November 12, 2019, 2:39am UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987 "2019-11-12T02:39:50Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![Adriel](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@Adriel](https://discourse.julialang.org/u/Adriel)\
**Post date:** [November 12, 2019, 2:39am UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/1 "2019-11-12T02:39:50Z")

</div>

(For anyone needing an excuse to procrastinate.)

Is this a very julian way to write this? How could it be improved?

```julia
function fizzbuzz(i, ps)
    s = [p.second for p in ps if p.first(i)] |> join
    return isempty(s) ? string(i) : s
end

ps = ((i->i%3==0) => "Fizz",
      (i->i%5==0) => "Buzz")

fizzbuzz.(1:20, Ref(ps))

```

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [November 12, 2019, 4:46am UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/2 "2019-11-12T04:46:18Z")

</div>

Here’s a prosaic version I might write in “real code”:

```julia
function fizzbuzz(i)
    f = i % 3 == 0
    b = i % 5 == 0
    f && b ? "FizzBuzz" :
    f ? "Fizz" :
    b ? "Buzz" : string(i)
end

for i in 1:20
    println(fizzbuzz(i))
end

```

Arguably this has the benefit of being straightforward, keeping the logic related to fizzing and buzzing in one place, separating the side effects, and not allocating more than “necessary” (maybe could be better in that way if we went direct to `IO`). It has the downsides of being boring and not generalizing to arbitrary predicates 😃

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [November 12, 2019, 5:09am UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/3 "2019-11-12T05:09:55Z")

</div>

```julia
ps = ((i->i%3==0) => "Fizz",
      (i->i%5==0) => "Buzz",
i->i%7 ==0)=>"Zap")

function fizzbuzz(n,ps)
    res = ""
    for (key,value) in ps
        if key(n) == true 
            res *= value
        end
    end
    if res == ""
        res *= string(n)
    end
    return res
end

julia> for i = 1:21
       println(fizzbuzz(i,ps))
       end

1
2
Fizz
4
Buzz
Fizz
Zap
8
Fizz
Buzz
11
Fizz
13
Zap
FizzBuzz
16
17
Fizz
19
Buzz
FizzZap

```

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [November 12, 2019, 5:23am UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/4 "2019-11-12T05:23:34Z")

</div>

> [@Adriel](#):
>
> ```julia
> s = [p.second for p in ps if p.first(i)] |> join
> 
> ```

maybe using a function to access the values rather that accessing the field directly?

```julia
s = [last(p) for p in ps if first(p)(i)] |> join

```

---

<div class="post-metadata">

**Author:** ![Adriel](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@Adriel](https://discourse.julialang.org/u/Adriel)\
**Post date:** [November 12, 2019, 10:07pm UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/5 "2019-11-12T22:07:26Z")

</div>

Yes, this is boring. But I looked at my code less than 24 hours after writing it and didn’t immediately understand it! So maybe boring is not such a bad thing.

Also, good point about removing allocations.

---

<div class="post-metadata">

**Author:** ![Adriel](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@Adriel](https://discourse.julialang.org/u/Adriel)\
**Post date:** [November 12, 2019, 10:12pm UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/6 "2019-11-12T22:12:55Z")

</div>

Thanks. As far as I can see this is essentially the same `fizzbuzz`, except it avoids creating an array of strings. Is that the point here?

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [November 12, 2019, 10:16pm UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/7 "2019-11-12T22:16:27Z")

</div>

I just wanted to do my own version 😅, but there are esencially the same, as they use the same arguments.

---

<div class="post-metadata">

**Author:** ![Adriel](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@Adriel](https://discourse.julialang.org/u/Adriel)\
**Post date:** [November 12, 2019, 10:19pm UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/8 "2019-11-12T22:19:52Z")

</div>

Just realised the array allocation

```julia
    s = [p.second for p in ps if p.first(i)] |> join

```

can be replaced with a generator.

```julia
    s = join(p.second for p in ps if p.first(i))

```

It’s faster too.

---

<div class="post-metadata">

**Author:** ![anon92994695](https://avatars.discourse-cdn.com/v4/letter/a/ce7236/32.png) [@anon92994695](https://discourse.julialang.org/u/anon92994695)\
**Post date:** [November 12, 2019, 10:25pm UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/9 "2019-11-12T22:25:10Z")

</div>

I’m so lazy here’s how I’d probably write it…

```nohighlight
FizzBuzz1(x) = ( (x % 3 == 0) ? "Fizz" : "") * ( (x % 5 == 0) ? "Buzz" : "")
FizzBuzz1.(1:30)

FizzBuzz2(x) = reduce( *, ["Fizz","Buzz"][(x .% [3,5]) .== 0])
FizzBuzz2.(1:30)

```

---

<div class="post-metadata">

**Author:** ![anon92994695](https://avatars.discourse-cdn.com/v4/letter/a/ce7236/32.png) [@anon92994695](https://discourse.julialang.org/u/anon92994695)\
**Post date:** [November 12, 2019, 10:40pm UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/10 "2019-11-12T22:40:00Z")

</div>

Awkward looks like I just failed my code interview! Here’s a quick monkey patch…

```nohighlight
function IfNothingThenX(fn, x) 
    result = fn(x)
    return ( length(result) == 0 ) ? x : result
end

IfNothingThenX.(FizzBuzz1, 1:30)
#Or...
IfNothingThenX.(FizzBuzz2, 1:30)

```

---

<div class="post-metadata">

**Author:** ![Adriel](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@Adriel](https://discourse.julialang.org/u/Adriel)\
**Post date:** [November 12, 2019, 10:59pm UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/11 "2019-11-12T22:59:07Z")

</div>

The `reduce` version gets my vote!

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [November 13, 2019, 12:23am UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/12 "2019-11-13T00:23:25Z")

</div>

> [@Adriel](#):
>
> So maybe boring is not such a bad thing.

Right! I feel it’s an uncomfortable fact that boring is often great for maintenance. Thought provoking reading: [Dan McKinley :: Choose Boring Technology](https://mcfunley.com/choose-boring-technology)

---

<div class="post-metadata">

**Author:** ![anon92994695](https://avatars.discourse-cdn.com/v4/letter/a/ce7236/32.png) [@anon92994695](https://discourse.julialang.org/u/anon92994695)\
**Post date:** [November 13, 2019, 1:15am UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/13 "2019-11-13T01:15:27Z")

</div>

Boring is usually the best for maintenance! Often good for performance too. People who write languages, write them to be used pragmatically (usually).

I have a proclivity to solve small units of code as quickly as possible. Sometimes it bites me, sometimes it saves me a bunch of trouble because 70% of it goes to the garbage heap or the metaphorical “never to be touched again” code file.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [November 13, 2019, 2:05am UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/14 "2019-11-13T02:05:24Z")

</div>

An ironic suggestion on the Julia mailing list 😬

I was working at Etsy with Dan (author of that blog post) when Kellan became the head of engineering. The effort to get rid of miscellaneous “exciting” technology was clearly the right thing to do. We did not need web services built in Clojure in company where most things were written in PHP. We also didn’t need MongoDB for one service when other things were all backed by MySQL.

However, at one point Kellan tried to convince me that it would be better to write a recommender system in PHP. And that’s where things become less clear cut. Could you write code that computes SVDs of sparse matrices in PHP? Honestly, I don’t know. For that application, PHP becomes an exciting technology rather than a boring one. You know what’s a boring technology for building a SVD-based recommender system? Matlab. So that’s what I used. Unfortunately, that entails deploying Matlab—fortunately not for serving recommendations, we precomputed those and stored them in MySQL to be served from PHP—but we did deploy Matlab for generating new recommendations each day;  
not a critical component since when it failed all that happened was that recommendations didn’t get updated, but still unpleasant and risky. Deploying Matlab is back in rather “exciting“ territory again. However, that seemed like the least exciting option available at the time.

That was in 2010, and Julia was just a weird side project that everyone made fun of me for working on in my spare time. (Having your own programming language is the tech equivalent of having your own religion—people back away slowly when you start to tell them about it, until it becomes well known and then it’s cool, I guess?) If it was today and I needed to build and deploy such a recommender system, Julia would be a nice boring technology for that. Python would also be a fine and arguably even more boring technology for it. Deploying Julia is, in any case, way more reasonable and boring than deploying Matlab was.

I think the bottom line is that you have a certain amount of novelty budget for an endeavor, so think hard about where you want to spend it and what you get in exchange.

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [November 13, 2019, 5:29am UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/15 "2019-11-13T05:29:33Z")

</div>

> [@StefanKarpinski](#):
>
> An ironic suggestion on the Julia mailing list

Haha! The irony ~~was not lost on me~~ was partly lost on me due to being several levels deep, thanks for the story! By the way I really do like that blog post but it makes me strangely uncomfortable at the same time. Perhaps it’s the problem of being a research scientist who knows enough systems engineering to be dangerous 😃 (or is it the other way around… I’m never quite sure anymore 🤔)

Having a novelty budget is a good way to think about the problem.

---

<div class="post-metadata">

**Author:** ![essenciary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/essenciary/32/210469_2.png) [@essenciary](https://discourse.julialang.org/u/essenciary)\
**Post date:** [November 13, 2019, 12:37pm UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/16 "2019-11-13T12:37:48Z")

</div>

This rings familiar from a developer and team lead perspective.

1 - we’ve been using PHP for over 10 years. It’s the least exciting language, almost as uncool as your neighbour’s 1997 Prius. However, _it just works_. The upgrade path from PHP 5 (or was it 4 when we started?!) to current 7 was simple and cheap. And you get very good performance with minimum tweaks (99% of the time the RDBMS is the bottleneck).

2 - however, there are things that a language will just be bad at, up to the point where it’s just not worth optimising for that. For us, it was processing very large amounts of XML data with PHP in real-time. We ended up choosing Go, but it was part of that research that I discovered Julia 😍 (Julia was just too young at that point, it must’ve been 0.4). We ended up with a pretty efficient services architecture in PHP and Go.

3 - as a developer, getting to work with new technology is fun and exciting and as the team lead I see this as a reward for the team. But as a team lead/CTO one must _very_ thoroughly weigh that against the fact that you’re adopting new languages which need expertise, recruiting, training, etc for long term maintenance. If your only Go dev leaves, you need to find a solution _fast_. So once you adopt a language, best to adopt it for a wide class of projects and tasks and understand that you’re committing to that language.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [November 13, 2019, 1:18pm UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/17 "2019-11-13T13:18:08Z")

</div>

With some coauthors, we are nearing a milestone (an actual draft of preliminary results, yay 🎉) of a medium-sized numerical project (solving a particular model), so at some point I will be tempted to write up a similar account of our experience for scientific computing, particularly in Julia, because we have a nice trail of benchmarks from the very beginning to a more than 100x speedup using various tricks (so now the runtime is just 2 days 😉).

The most important lesson at this point is to get _one working version_ of the whole computation stack before any algorithmic or optimization. This is mentally difficult to do, because we all know that whatever ends up there will be completely rewritten N times (currently, at least N = 6 for us) so it all seems like wasted effort. But without something to profile and benchmark, we would probably misallocate our “optimization budget”.

The unexpectedly nice thing about Julia is how easy it is to write “loosely coupled” code that can be optimized and benchmarked in small pieces. So, we can experient with replacing a `Vector` with a `StaticVector`, or allocating in an object pool for some parts, or switch AD libraries, pretty much without rewriting anything else. This in itself makes up for the wholes in the ecosystem.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [November 16, 2019, 1:56am UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/18 "2019-11-16T01:56:15Z")

</div>

Not strictly related but just a delightful rant form Dan about even earlier days at Etsy than I was there for:

> <https://twitter.com/mcfunley/status/1194713711337852928>
>
> kellan@fiasco.social @kellan

Part of the moral of the story is that even though Python + Twisted is a perfectly boring technology, boringness is context dependent: as a middleware later in a PHP stack, Python is totally unnecessary.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [February 28, 2023, 8:52pm UTC](https://discourse.julialang.org/t/please-critique-my-fizzbuzz/30987/19 "2023-02-28T20:52:49Z")

</div>

39 posts were split to a new topic: [Code-golfing FizzBuzz](https://discourse.julialang.org/t/code-golfing-fizzbuzz/95354)
