A Pipeable Logger

The Elixir Logger is pretty good. You can easily log anything with it, just call one of debug, info, warn or error. For example:

1
Logger.info("something happened")

Turns into:

12:34:56.789 [info]  something happened

Very nice. However, there are cases where you may want to, say, change some data structure, like update a map or a list, and then log the transition, without breaking the pipe. Example:

1
2
3
4
5
6
7
8
def my_function do
  list = [1, 2, 3]

  list
  |> Logger.debug("before insert: #{inspect list}")
  |> Enum.into([0])
  |> Logger.debug("after insert: #{inspect list}")
end

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:

1
2
3
4
5
6
7
8
9
10
11
12
def my_function do
  [1, 2, 3]
  |> (fn list ->
    Logger.debug("before insert: #{inspect list}")
    list
  end).()
  |> Enum.into([0])
  |> (fn list ->
    Logger.debug("after insert: #{inspect list}")
    list
  end).()
end

If we call this function, we get:

12:34:56.789 [debug] before insert: [1, 2, 3]

12:34:56.823 [debug] after insert: [0, 1, 2, 3]

Great, exactly what we want! Except the syntax is horrible. But fear not, we can improve on it. How about we make a wrapper?

1
2
3
4
5
6
7
8
9
10
11
12
13
defmodule PipeableLogger do
  require Logger

  def debug(data, msg) do
    Logger.debug(msg)
    data
  end

  # def warn, do: ...
  # def error, do: ...
  # def info, do: ...

end

Let’s rewrite our function once again:

1
2
3
4
5
6
def my_function do
  [1, 2, 3]
  |> (&PipeableLogger.debug(&1, "before insert: #{inspect &1}")).()
  |> Enum.into([0])
  |> (&PipeableLogger.debug(&1, "after insert: #{inspect &1}")).()
end

Still not pretty though, as we still needed to wrap the function in a lambda. If we want to build a proper Logger wrapper, there are at least two different cases we may want to handle:

  1. Logging a simple message (without any data);
  2. Logging the data we receive from the pipe, maybe also with a message.

Here’s the improved version of PipeableLogger:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
defmodule PipeableLogger do
  require Logger

  def debug(data, msg \\ "", metadata \\ [])
  def debug(data, msg, metadata) when msg == "", do: Logger.debug(data, metadata)
  def debug(data, msg, metadata) do
    Logger.debug(msg, metadata)
    data
  end

  # def warn, do: ...
  # def error, do: ...
  # def info, do: ...

end

Let’s use it:

1
2
3
4
5
6
def my_function do
  [1, 2, 3]
  |> PipeableLogger.debug("before insert")
  |> Enum.into([0])
  |> PipeableLogger.debug("after insert")
end

Much, much simpler! The only problem now is, we’re logging just a message. What if we want to log the data? It’s a lambda all over again.

Here’s the final version I came up with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
defmodule PipeableLogger do
  require Logger

  def debug(data, msg \\ "", metadata \\ [])
  def debug(data, msg, metadata) when msg == "", do: Logger.debug(data, metadata)
  def debug(data, msg, metadata) when is_binary(data) do
    Logger.debug(msg <> data, metadata)
    data
  end
  def debug(data, msg, metadata) do
    Logger.debug(msg <> inspect(data), metadata)
    data
  end

  # def warn, do: ...
  # def error, do: ...
  # def info, do: ...

end

The assumption is that we always want to concatenate the data with the message, which is fair enough I think. Let’s see it in action:

1
2
3
4
5
6
def my_function do
  [1, 2, 3]
  |> PipeableLogger.debug("before insert: ")
  |> Enum.into([0])
  |> PipeableLogger.debug("after insert: ")
end
1
2
3
4
5
6
iex> my_function()

12:34:56.789 [debug] before insert: [1, 2, 3]

12:34:56.789 [debug] after insert: [0, 1, 2, 3]
[0, 1, 2, 3]

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:

1
2
config :logger, :console,
  metadata: [:my_list]

You can then call Logger like this:

1
2
3
4
5
6
7
iex(1)> require Logger
Logger

iex(2)> Logger.info "Work done", my_list: inspect [1, 2, 3]

12:34:56.789 my_list=[1, 2, 3] [info]  Work done
:ok

Point is, you don’t need a wrapper if all you want is concatenate some data in the log message. You do need a wrapper though (or a lambda) if you want to use Logger in a pipe.

So how about this instead?

1
2
3
4
5
6
def my_function do
  list = [1, 2, 3]
  Logger.debug("before insert: #{inspect list}")
  new_list = Enum.into(list, [0])
  Logger.debug("after insert: #{inspect new_list}")
end

Simple is better. It’s fine to break that pipe every once in a while!

Recursive Reduce in JavaScript and Clojure

Another fun kata:

Given an array of arbitrarily nested objects, return a flat array with all the objects marked as “good”.

The definition above is quite generic, so I’ll provide examples to show exactly what I mean.

The array in JavaScript looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var items = [{
    id: 1,
    good: true
}, {
    id: 2,
    children: [{
        id: 3,
        good: true
    }, {
        id: 4,
        good: true
    }, {
        id: 5,
        children: [{
                id: 6,
                good: true
            }
            ...
        ]
    }, {
        id: 9,
        children: [...]
    }, ...]
}, ...]

We want the IDs of the good ones.

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.

Here it is:

1
2
3
4
5
6
7
8
9
10
11
12
function goodOnes(items) {
    return R.reduce(theGoodOne, [], items);

    function theGoodOne(acc, item) {
        if (item.good) {
            return acc.concat(item.id);
        } else if (item.children && item.children.length > 0) {
            return R.reduce(theGoodOne, acc, item.children);
        }
        return acc;
    }
}

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:

1
2
3
4
5
6
7
8
9
(defn good-one [acc item]
  (if (item :good)
    (conj acc (item :id))
    (if (seq (item :children))
      (reduce good-one acc (item :children))
      acc)))

(defn good-ones [collection]
  (reduce good-one [] collection))

Demo & Download

Everything is on GitHub if you want to fiddle around – just follow the instructions to get the demos up and running on your computer.

Blending together two lists in Elm and Swift

Here’s a fun kata:

Create a blend function that, given two lists of the same length, returns a new list with each element alternated. E.g.:

blend [1, 2, 3] [4, 5, 6]
=> [1, 4, 2, 5, 3, 6]

As with all challenges, it can be solved in many different ways. However this particular one is easily solvable with functional programming techniques such as recursion.

You can try implementing it on your own first or just look straight at the solutions below.

Solution in Elm

The one below is probably the most straightforward solution:

1
2
3
4
5
blend : List a -> List a -> List a
blend xs ys =
    case xs of
        x :: xs' -> x :: blend ys xs'
        _ -> []

Notice how I exchanged the arguments in the recursion call. That did the trick!

Let’s try it in the REPL – I added slashes so you can copy-paste the function:

1
2
3
4
5
6
7
8
9
10
11
$ elm-repl

> blend xs ys = \
    case xs of \
        x :: xs' -> x :: blend ys xs' \
        _ -> []

<function> : List a -> List a -> List a

> blend [0,0,0] [1,1,1]
[0,1,0,1,0,1] : List number

Solution in Swift

We can achieve the same in Swift by using an extension that splits up an Array into head and tail (credits to Chris Eidhof):

1
2
3
4
5
extension Array {
    var match : (head: T, tail: [T])? {
      return (count > 0) ? (self[0],Array(self[1..<count])) : nil
    }
}

And here’s the solution:

1
2
3
4
5
6
7
func blend(firstArray: Array<AnyObject>, secondArray: Array<AnyObject>) -> Array<AnyObject> {
    if let (head, tail) = firstArray.match {
        return [head] + blend(secondArray, secondArray: tail)
    } else {
        return []
    }
}

If you know of a better way, please let me know! Also feel free to leave a comment with any other alternative solution, even in other languages.

How to get the AST of an Elixir program

Getting the AST (Abstract Syntax Tree) representation of an Elixir source is pretty simple.

Let’s say we want to get the AST of this file:

lib/hello.ex
1
2
3
4
5
6
7
defmodule Hello do

  def hi(name) do
    IO.puts "Hello " <> name
  end

end

We can do it right away from iex:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ iex
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:8:8] [async-threads:10] [kernel-poll:false]

Interactive Elixir (1.0.5) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> {:ok, ast} = Code.string_to_quoted(File.read!("lib/hello.ex"))
{:ok,
 {:defmodule, [line: 1],
  [{:__aliases__, [counter: 0, line: 1], [:Hello]},
   [do: {:def, [line: 3],
     [{:hi, [line: 3], [{:name, [line: 3], nil}]},
      [do: {{:., [line: 4],
         [{:__aliases__, [counter: 0, line: 4], [:IO]}, :puts]}, [line: 4],
        [{:<>, [line: 4], ["Hello ", {:name, [line: 4], nil}]}]}]]}]]}}

In our case, the ast variable will contain the full AST of the source code.

In case you want to get the AST of a single line, it’s even simpler:

1
2
3
4
5
6
7
8
9
10
iex(1)> name = "John"
"John"

iex(2)> IO.puts "Hello " <> name
Hello John
:ok

iex(3)> ast = quote do: IO.puts "Hello " <> name
{{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [],
 [{:<>, [context: Elixir, import: Kernel], ["Hello ", {:name, [], Elixir}]}]}

For more context, I recommend reading the introduction to meta-programming in Elixir on Elixir’s official site.

In case you’re interested in parsing Elixir, Tokenizing and parsing in Elixir with yecc and leex by Andrea Leopardi is a very recommended reading.

Have fun with Elixir!

How To Get Environment Variables in the Browser

Preface: Why?

Environment variables are very useful for configuring your app depending on the environment, without having to hardcode any value in the source.

At my current company we are building a microservice infrastructure, where the frontend and the backend are completely decoupled applications. We also use Docker to manage these microservices and link them together. Turns out that storing the configuration in the environment—as opposed to storing it in the database or in the code itself—is quite valuable, as described also in the twelve-factor methodology.

Advantages:

  • Language and OS agnostic;
  • Easy to change between deploys without changing any code;
  • Impossible to accidentally check in source control.

How?

A web page doesn’t have access to OS variables, so you can’t normally use them.

The solution is pretty simple: you just need to generate a file that contains them.

For such a trivial task you could be tempted to use your language of choice, e.g. in JavaScript (Node.js) you have access to process.env.SOME_VAR. In Python you would probably do os.getenv('SOME_VAR') and in Ruby you’d use ENV['SOME_VAR']—but what about some old-school shell scripting? The script could be as simple as:

bin/env.sh
1
2
3
4
echo "env = {"
echo "  USER: '$USER',"
echo "  HOSTNAME: '$HOSTNAME'"
echo "}"

That, when executed, will become:

env.js
1
2
3
4
env = {
  USER: 'simone',
  HOSTNAME: 'ubuntu'
}

And the script to execute is:

1
$ ./bin/env.sh > env.js

Pretty straightforward, isn’t it?

Test it:

<!DOCTYPE html>
<html>
<head>
  ...
</head>
<body>
  <script src="env.js"></script>
  <script>
    console.log(env.USER +'@'+ env.HOSTNAME); // "[email protected]"
  </script>
</body>
</html>

One downside to this approach is that you have to “make a build” every time you change the variables. If you know any workarounds or better solutions, please let me know!

Source and download

Find the source code on GitHub. Download the zip file here.

Have fun!