Back in the days, when I got serious about becoming a “real programmer”, I decided I wanted to learn Java.

I didn’t know anything about OOP, Design Patterns, Single Responsibility… all I knew was some PHP, Visual Basic, and database design stuff. That was it.

So I went to a book store and I bought this book about Object-Oriented Programming in Java 6. It was a massive book, probably around 1000 pages of code and programming best practices, and I read like 80% of it. Some parts were too advanced for me, but I learned a lot.

I used to like Java. I thought, “so this is what real programming looks like, with classes and inheritance. That’s the right way”.

I actually believed this for a while, until that day…

One day I went to this website, projecteuler.net, which is basically a way to prove your skills by solving difficult programming challenges, and learn in the process.

It was years ago, but I remember I solved the first couple exercises pretty easily. The third one was a bit harder. Here’s the original text:

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.

Find the largest palindrome made from the product of two 3-digit numbers.

I couldn’t believe my eyes. I was staring at something marvelous; some beauty that I never came across before.

Ruby is an object-oriented programming language that focuses on expressiveness and readability.

It was love at first sight. I started reading about this amazing language, about the fact that everything in Ruby is an object, even integers, and that you can write code like 3.times { print "Hello" } to simply print “Hello” 3 times. It was like reading English, and I felt truly amazed, humbled, and inspired.

Anyway, that’s just part of my story about becoming a better programmer. I’m not sure what the point is, I just felt like writing it down. But if, like me, you’re one of those people that need some ‘takeaway’ from a story, I guess it should be this:

Just don’t stop learning, ever.

Keep on learning and practicing, and you too will discover beautiful things.

This doesn’t work for many reasons. First, we can’t refer to list that way. If we do, we will always be logging [1, 2, 3], because Elixir’s data structures are immutable.
Second, Logger.* functions return the :ok atom, which means you can’t use them in a pipe—unless that is what you want to return.

The solution to both issues is actually pretty straightforward: use a lambda!
A lambda is just an anonymous function. We can define it and call it right away. So the code above becomes:

Now we can log the data with a message, all in a pipe and without a lambda! Nice!

Summing up, I’m not convinced a Logger wrapper is the right way. This kinda goes against the blog post, but to be fair I think Elixir people tend to use pipes way too much (I’m guilty as well). So I wouldn’t probably wrap Logger in any project.

It’s also worth noting that Logger supports the concept of metadata, which basically means you can already attach any data you want. For example, if you put this in your config.exs:

You might have noticed not all objects are “good”. Number 2 for example
is not good. So the result in this case should be:

1

[1,3,4,6]

The only thing to notice here is that you know it’s not good because
it’s not marked as such. In other words, when some object is “bad”,
there’s no good: false nor bad: true that tells you that.

So how do we solve this challenge?

Since there’s an arbitrary nesting depth, we can once again leverage the
power and simplicity of recursion.

Solution in JavaScript

I’ve created the function goodOnes(items) that takes the input and
returns what we expect. I’m also using Ramda.js, just because I wanted a clean functional solution and I didn’t want to mess around
object mutation.

As a side note, you don’t really have to use Ramda.js.
Array.prototype.reduce does the same, although in a less elegant way.

Explanation

What this function does is basically just collecting values. The
starting point is an empty array, you can see that as the second
argument in the first line. theGoodOne is another function (a closure,
to be specific) that is implicitly taking two arguments: acc (the
accumulator, the empty array) and item (the current item in the loop).

If the item is good, we return a new array with the item’s ID.
Otherwise, we return the accumulator. However, if the item happens to
have some children, we start over doing the same thing (i.e. looping
over its children), also keeping track of the accumulator we already
have this time. It might be still empty, but we don’t care yet. We just
return it at the very end.

Now, you might have noticed a bug: what happens if the item is good, but also
has children? … Yes, that item will be discarded! I did it on purpose
by the way. When I made this function, the original array of items never
had any good item with children. Only good items, or items with children.
The algorithm is reflecting this, so it’s technically not a bug.

If you’re curious about what’s the original intent behind this function, it is to
collect values from an infinitely nestable architecture of UI components.
There are text components, number components, datepickers etc…
those are all part of a category called fields. There are also
wrappers, that could be for example a fieldset or a grid. Wrappers can
contain fields, but also other wrappers.

So what if you have such data structure with so many components and all
you need is just an array of fields? Simple, just reduce recursively
on it! ;)

More in general, you can use the recursive reduce whenever you have
a nested data structure (such as an array of arrays) and you want to get something out of it.

Solution in Clojure

This recursive solution follows the same logic as the JavaScript
one, but somehow it feels superior. It could probably be rewritten in a
more elegant way I guess, but I’m not very experienced with Clojure so
here we go: