Elixir and Javascript syntax comparison
Tags: javascript, elixir, syntax, codenewbie
Published: 2020-09-24 13:31:11

On a daily basis at work I use 2 languages. Java and Javascript.
Doing Javascript everyday and learning Elixir, I recognize some patterns. Let's recap.

Nobody ignores in the web dev planet the features that ES6 ships to the Javascript language, especially the functional ones.

## Summary

1. Objects vs Modules
2. Method chaining vs Pipe Operator
3. Destructuring vs Pattern Matching
4. High Order Functions

### Objects vs Modules

With ES6, the `class` keyword and all the *OO* ceremony come in `Javascript`.
In `Elixir`, as a functional language, it doesn't support the idea of `Object`, instead, we've `Modules`, which can be seen as bucket or namespace for functions.

Example of an `Object` in `Javascript`:

```javascript
const Circle = {
  PI: Math.PI, // Math.PI is a constant
  area: r => Circle.PI * (r ** 2),
  circumference: r => Circle.PI * (r * 2)
};

Circle.area(2) // 12.56...
```

Same in `Elixir`:

```elixir
defmodule Circle do
  @pi :math.pi() # Here we define a module constant

  def area(r), do: @pi * (r * r)
  def circumference(r), do: 2 * @pi * r
end

Circle.circumference(5) # 31.41..
```

So in my opinion, I've gained some good habits from *FP*, like writing little functions, which are responsible of a ~~tiny modification of the input~~ new output based on the one passed, and the modification asked. So that's what we call a reducer.
And this, let us build very complex data transitioning with ease, so it leads us naturally to the next step: ***Method Chaining vs Pipe Operator***.

---

#### A bit of background: Erlang and Elixir

In a precedent example, I've used `:math.pi()` which is not an Elixir module, here's why.
Unlike `Javascript`, `Elixir` does not have a Math module, instead, it leverage the `Erlang` standard library. In fact, `Elixir` is built on top of `Erlang`. Furthermore, `Elixir` and `Erlang` are interoperable. Which means we can use the huge ecosystem of `Erlang` libraries in our `Elixir` code. That's pretty neat.
So to call an `Erlang` module in `Elixir`, we just have to type the following:

```elixir
:erlang_module.erlang_function()
:math.pi()
:crypto.hash(:md5, data) # To use crypto library and hash with MD5
```

---

### Method Chaining vs Pipe Operator

So here we are going to take a real-world example, squaring a list of numbers and reducing the value to a single one. So we can use in both languages the map and reduce functions.

`Javascript`

```javascript
const numbers = [1,2,3,4,5]\
let sumOfSquares = list
  .map(num => num * num)
  .reduce((num, acc) => acc + num)
```

In `Elixir`, we will use the pipe operator

```elixir
list_of_numbers = [1,2,3,4,5]
sum_of_squares =
  list_of_numbers
  |> Enum.map(&(&1 * &1))
  |> Enum.reduce(&(&1 + &2))
```

Two things here which are `Elixir` specific, first the `|>` aka pipe operator and second, this exotic piece of syntax '**`&(&1)`**'.

So the pipe operator let us pass the data from a function call to another in a Unix shell fashion. But, as uncle Ben told us, with great power comes great responsibility, *well ... kidding*, here there's just one rule, your first function parameter should be the output of the previous function. That's all. So `map` in both `Javascript` and `Elixir` returns an `Array` or a `List` (same thing but different naming).

To truly leverage this pipe operator, you must think in function composition. Here's an example for a simple scrapper that I wrote.
I needed to perform a call to a specific URL, handle the 301 HTTP status, get the correct URL and then make a new call to the properly formatted URL.

```elixir
def get_url(ean) do
    HTTPoison.start()
    url =
      "#{@url}-#{ean}" # Module constant here
      |> HTTPoison.get!() # Call to another Module function
      |> get_html() # Module function
      |> get_title() # Module function
      |> List.to_string() # List Module function call
      |> split() # Module function
  end
```

So this pipe operator avoid one thing, function call hell like this:

```javascript
function3(function2(function1(data))) // works but we loose readability
```

The pipe operator put the data where it should be. At the top of the attention, after all, that's what we are processing.

As far as I recall, it seems that the pipe operator is in a proposal stage at the TC39. Anyway, it's also available in ReasonML, so in React-Reason.

And what if I told that we can extract data of a variable easily by just describing what we want ?

### Destructuring vs Pattern Matching

In `Elixir`, we say `x = 1`, you probably think that `x` is equal to `1`. But there's a subtle difference, we do not say this is equality, we say its a match. The value behind `x` is `1` because we have bind the free variable named `x` to match the value of `1`. So the `=` sign is called the `match operator` and not `equal`.

Thinks of this as a comparison between the `Rhs` and the `Lhs`. See how we can leverage this.

Taking MDN docs, destructuring is:
> The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.

So:

```javascript
let a, b, rest;
[a, b, ...rest] = [10, 20, 30, 40, 50]; // ... or spread operator
a // 10
b // 20
rest // [30, 40, 50]
```

In `Elixir`:

```elixir
list = [1,2,3,4,5]
a, b = list
** (SyntaxError) iex:2: syntax error before: ','
```

Oh, it seems that it doesn't work like in `Javascript`... So here, `list` is a `List` type. And in `Elixir`, a list is a made of a head and a tail like this `[head | tail]` ( the pipe here is called the cons operator).
Thus, we can write a list like this `[1 | [ 2 | [ 3 ]]]`.
Lets do this in the `Elixir` fashion.

```elixir
list = [1,2,3,4,5]
[a|b] = list
a # 1
b # [2,3,4,5]

# One more time
[a, b, c|d] = list
a # 1
b # 2
c # 3
d # [4,5]
```

In `Javascript`, destructuring is really great, especially in function parameters.

Like in this React component, instead of calling `props.title`, `props.imageUrl`, etc.
I choose to destructure the props parameter and cherry-pick the values I want to get from.

```javascript
render() {
  return (
   <div className="directory-menu">
    {
     this.state.sections.map(({title, imageUrl, id, size}) => (
      <MenuItem key={id} title={title} imageUrl={imageUrl} size={size} />
     ))
    }
   </div>
  );
 }
```

As I did in this `Elixir` snippet:

```elixir
def draw_image(
  %Identicon.Image{color: color, pixel_map: pixel_map})
  do
    image = :egd.create(250, 250)
    fill = :egd.color(color)

    Enum.each pixel_map, fn({start, stop})  ->
      :egd.filledRectangle(image, start, stop, fill)
    end

    :egd.render(image)
  end
```

To extract the values from the `Identicon.Image` struct, I pattern matched on the fields of the passed struct in the function parameter. But what if we can call functions in function parameters?

### High Order Function

In `Elixir`, function are first-class citizens, so a function can take a function as a parameter and/or return a function.

So let's get a non-trivial example!

```javascript
// In ES6 style
const multiplyAll = array => times => array.map(
  item => item * times
);

// In ES5 style
var multiplyAll = function multiplyAll(array) {
  return function (times) {
    return array.map(function (item) {
      return item * times;
    });
  };
};

multiplyAll([2,7,3,60])(2) // [4, 14, 6, 120]
```

This what we call 🍛 🙌 [CURRYFICATION](https://javascript.info/currying-partials) 🍛 🙌!

We can see in ES5 style that we have a function, which returns a function, which uses a method with a lambda AKA anonymous...function!

#### Yo Dawg, I've heard you like functions so we put functions in your functions which returns functions in the function body... 🤔

In fact it helps a lot. See, we can leverage this style to prevent side effects, and aims pure functions.

In `Elixir`, we can do this, this way:

```elixir
# Here we declare a lambda called run_query
run_query =
  fn query_def ->
    Process.sleep(2000)    ①  
    "#{query_def} result"
  end

# Here another lambda with the previous one inside.
async_query =
  fn query_def ->
    spawn(fn -> IO.puts(run_query.(query_def)) end)
  end

# And finally, we use this lambda in another function call
Enum.each(1..5, &async_query.("query #{&1}"))

# Naively we can achieve this this way
add = fn x ->
  fn y -> x + y end
end

add.(1).(3) # 4
```

This ends the Javascript vs Elixir article, the main goal is not to make a real comparison between the languages but much more leverage the strength of one language to write better code.

As I said earlier, since I've begun my Elixir journey, I realize how I can leverage Elixir's idioms and philosophy to write better Javascript, and vice-versa.

Kudos to you if you have reach the end of this.