loading...

Things I wish I can use in React/Javascript from Elixir

tehaisperlis profile image Hazmi Irfan ・3 min read

First, I would like to say that this is not a list of complaints but more of a wish list. I have no problem with Javascript and I think each language has it's own strength.

Having said that, below are some of the things I wish I can use in Javascript that is inspired by my experience of using Elixir.

Pattern Matching Function

One of the thing that makes me like Elixir so much is the ability to do pattern matching everywhere. It makes the code so much cleaner.

For example, imagine you need to show 3 type of component depending on the data. Normally you would do something like this:

const Item = (type) => 
{
 switch(type){
  case "A": <ItemA/>
  break;
  case "B": <ItemB/>
  break;
  case "C": <ItemC/>
  break;
 }
}

Enter fullscreen mode Exit fullscreen mode

Although this is okay but using pattern matching, you can write it like this:

const Item = ("A") => 
{
  return <ItemA/>
}
const Item = ("B") => 
{
  return <ItemB/>
}
const Item = ("C") => 
{
  return <ItemC/>
}

Enter fullscreen mode Exit fullscreen mode

Yes, in Elixir you can have function with the same name but differentiate it with pattern matching.

For me this way is much cleaner especially if you need to add more logic to each of the render function.

Also, if you are using Redux like me, you can also write it a lot cleaner without additional library. Example of a normal Redux would be:

//reducer.js
function counterReducer(state, action) {
  switch (action.type) {
    case 'incremented':
      return { value: state.value + 1 }
    case 'decremented':
      return { value: state.value - 1 }
    default:
      return state
  }
}
Enter fullscreen mode Exit fullscreen mode

With pattern matching you can write it like this :

//reducer.js
function counterReducer(state, 'incremented') {
  return { value: state.value + 1 }
}

function counterReducer(state, 'decrement') {
  return { value: state.value - 1 }
}

function counterReducer(state, _) {
  return state
}

Enter fullscreen mode Exit fullscreen mode

If you are wondering what is _, it is a syntax to explicitly ignore the variable, making it behave like the default case.

Pipe operator

Pipe operator is an alternative way and in my opinion, a cleaner way to handle nested function. This is especially useful if you are writing React in a functional way.

For example, imagine you have a data that you would need to
1) Get the amount.
2) Convert it into an Integer.
3) Increase it by 5.
4) Convert it into a String.

You can do something like this:

const amount = add((parseInt(getAmount(object))), 5).toString(); 
Enter fullscreen mode Exit fullscreen mode

I admit that this is an extreme way of writing it. But with a pipe function you could do something like this:

const amount = 
  getAmount(object) 
  |> parseInt()
  |> add(5)
  |> toString()
Enter fullscreen mode Exit fullscreen mode

This is much more readable for me. Again if you are wondering, with the pipe operator, the return value of a function will be passed to the next function as the first parameter.

Immutable variable

I think this is more self explanatory. If you are writing your code in a functional way or are using library that heavily rely on your data to be immutable like Redux, having out of the box support for immutability makes it so much easier and simple.

Atom

In Elixir, An Atom is defined as A constant whose value is its own name..

Instead of writing:


// reducer.js
export const INCREMENTED = "INCREMENTED"
export const DECREMENTED = "DECREMENTED"

function counterReducer(state, action) {
  switch (action.type) {
    case INCREMENTED':
      return { value: state.value + 1 }
    case DECREMENTED':
      return { value: state.value - 1 }
    default:
      return state
  }
}
Enter fullscreen mode Exit fullscreen mode

You could write it like this:

//reducer.js
function counterReducer(state, :incremented) {
  return { value: state.value + 1 }
}

function counterReducer(state, :decrement) {
  return { value: state.value - 1 }
}

function counterReducer(state, _) {
  return state
}
Enter fullscreen mode Exit fullscreen mode

That's it. You don't need to initialize the value since you can infer it from the name of the variable itself. This makes it a lot easier when you are writing Redux. You no longer need to declare the action type 1 by 1.

So these are some of the things I wish I can do in React or Javascript in general. I know Elm exists but for me, React and React Native is too good of library to stop using it.

Discussion

pic
Editor guide
Collapse
alfredosalzillo profile image
Alfredo Salzillo

For the first and second points, there are some proposals in stage in the ecma365, for adding patter matching with switch expressions, pipeline operator and currying operator.
For the Atom you can use Symbols.
Immutability can be achieved using constants and Object freeze.

Collapse
tehaisperlis profile image
Hazmi Irfan Author

For the first and second points, there are some proposals in stage in the ecma365, for adding patter matching with switch expressions, pipeline operator and currying operator.
Cool. Looking forward to it!

For the Atom you can use Symbols.
Unfortunately you still have to initialize the symbol which for me is still the same as creating a constant.

Immutability can be achieved using constants and Object freeze.
You can still change the nested value of const and Object freeze unless you do a deep freeze which I believe is a bit costly.