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;
}
}
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/>
}
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
}
}
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
}
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();
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()
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
}
}
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
}
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.
Top comments (3)
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.
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.
You could try ReScript along with React. It is a fully functional language inspired by OCaml that transpiles to JS