An Unprecedented Subtraction

Brujo Benavides
Erlang Battleground
4 min readJul 2, 2019

--

Let’s go back to the origins of this blog with a bit of unexpected code behavior. This time, let’s try removing elements from a list…

Maxwell Smart — because I couldn’t find any proper image for this article

Let’s Subtract!

The beauty of this trick is that the code examples work in both Erlang and Elixir, with barely any changes at all… I’ll do it in Elixir, feel free to try them out in Erlang or efene if you like.

Now, this is a list…

iex(1)> [1, 2, 3]
[1, 2, 3]

And now, we can subtract a few elements from it…

iex(2)> [1, 2, 3] -- [1, 2]
[3]

Let’s now subtract that last one, too…

iex(3)> [1, 2, 3] -- [1, 2] -- [3]
[3]
Santa Clarita Diet — Confusing, I know

What’s going on here?

As usual, it’s better if you first try to decipher the mystery on your own. So, go ahead, check the docs…

Have you found it? Do you know what’s happening?

To be fair, if you’re an Elixir dev you’re in a slightly better situation than your Erlang counterparts: The documentation is, I believe, much clearer.

But, let’s go step by step. First, let’s see what happens if we add parentheses to our expression…

iex(6)> ([1, 2, 3] -- [1, 2]) -- [3]
[]
iex(7)> [1, 2, 3] -- ([1, 2] -- [3])
[3]

That actually makes sense! It looks like -- associates from right to left. Let’s see if we can find documentation that proves it.

In Elixir

What we’re looking for is operator associativity. And elixir actually has a whole page in the docs dedicated to it. There you can see that all binary (as in “with two arguments”) list operations (++ -- .. and <>) associate from Right to Left.

That was easy.

As an aside: Let’s try to verify one if .. is actually right associative…

iex(7)> 1 .. 10
1..10
iex(8)> 1 .. 10 .. 20
** (ArgumentError) ranges (first..last) expect both sides to be integers, got: 1..10..20
(elixir) lib/range.ex:55: Range.new/2

In Erlang

Now let’s try to find that same thing in Erlang… 🕵️‍♀️

Well… There is no page for operator associativity, but if you google carefully you’ll be redirected to the docs for Erlang expressions. There, deep down, in the last part of that page, you’ll find a table dedicated to operator precedence

Table 8.6: Operator Precedence

If you squint a bit, you’ll find ++ and -- there and then you’ll see that they’re both Right associative. Just like =!

Wait… what?

What’s =!? I’ve never seen such an operator in Erlang…

That’s because there is no =! in Erlang. What that row is actually stating is that both = and ! are right associative.

Which is actually cool since it let’s you do stuff like…

1> self() ! self() ! self() ! something.
something
2> flush().
Shell got something
Shell got something
Shell got something
ok
3> Pid1 ! Pid2 ! Pid3 ! something. # "broadcast" a message :P

Is that it?

Yeah, I know… this article is not very insightful, deep or revealing as others, but this topic was in sitting in my To-Write list for almost 2 years. Now it’s out of the way.

In Other News…

SpawnFest

As I mentioned in my previous article, SpawnFest is coming!
This year it will happen on September 21st & 22nd.
Register your team and join us for FREE to win several amazing prizes provided by our great sponsors!

ElixirConfLA

ElixirConf is coming to Latin America for the first time!
Thanks to our friends from PlayUS Media, we’ll meet on Medellín, Colombia for ElixirConfLA on October 24th & 25th.
The schedule was already announced, Early Bird Tickets are on sale and the CFT is open until July 19th.

Erlang Battleground

Finally, the usual reminder: We’re looking for writers. If you want to write on Erlang Battleground, just le me (Brujo Benavides) know :)

--

--