Ramdajs - Functional Programming for Javascript
Warning: this post is written with my poor english
What is Ramda?
In short, Ramda is a utility library like underscore and lodash.
The different thing is that it strictly follows the Functional Programming (FP) style in its philosophy. Therefore, by using it you will be introduced to style of FP which, IMHP, will change the way you program and think when you program.
Should I learn to use and use Ramda?
Speaking for myself, the answer is definitely yes, because:
- For the sake of learning, I believe in long life learning
- It is always good to stay update with new tech, btw this is not new FP is something considered fundamental in programming
- Hopefully, I will write better code if I use Ramda right
And for you, I do not know. But I do advise you give it a try, it is always good to exposed to new idea.
Ramda core features
Immutability
In functional programming, mutable state is considered extremely dangerous, marking programs hard to reason about, difficult to debug, and almost impossible to grow correctly into large, consistent systems. Ramda helps avoid this by refusing to ever mutate input data.
Avoiding side effects
By preventing mutating input data, Ramda also helps to avoid side effects. By not mutating input data, your function will be pure. Other functions use the same input with your function get what they expect.
Composing functions
Ramda encourges to write pure, re-useable, small functions. Then compose those functions to work on your data. This will make the code cleaner, debug-able, re-useable, maintainable.
Currying everywhere
As describe in this talk Hey Underscore, You’re Doing It Wrong!, data should come last in the arguments list to make function more reusable. Ramda requires data to be the last arg in the function signature so that it is easier to make function curried automatically. With Ramda it is guaranteed that all functions and returned function are curried automatically.
For me this is a stunning feature, it allows us to maximize the reusability of function. In the nutshell, let say before you pass in your data and get the result, everything are reusable.
Let’s try some examples
This is our data:
const studentList = [{
name: 'dOg',
nickname: ' goofY ',
score: {
js: 7,
html: 8,
css: 9,
},
}, {
name: ' caT ',
nickname: 'tom',
score: {
js: 6,
html: 7,
css: 8,
},
}, {
name: 'MOUSE',
nickname: ' jerry',
score: {
js: 8,
html: 9,
css: 10,
},
}];
And there are three requirements:
- Tell me who are your students
- Tell me their js score
- Tell me their gpa
Tell me who are your students
const getName = R.prop('name');
const getListName = R.map(getName);
getListName(studentList); // -> ['dOg', ' caT ', 'MOUSE']
Ok, I have their names now, but can you do a little format stuffs? (trim, normalize)
const getName = R.prop('name');
const headToUpper = R.map(R.join(''), R.adjust(R.toUpper, 0));
// headToUpper('dOg') -> Dog
const normalizeStr = R.curry(R.composeK(
headToUpper,
R.toLower,
R.trim,
R.__
));
const getListName = normalizeStr(getName);
getListName(studentList); // -> ['Dog', 'Cat', 'Mouse']
Good, what about their nicknames??
const getNickname = R.prop('nickname');
const getListNickname = normalizeStr(getNickname);
getListNickname(studentList); // -> ['Goofy', 'Tom', 'Jerry']
Tell me their js score
const getScore = R.prop('score');
const getJs = R.prop('js');
const getJsScore = R.composeK(getJs, getScore);
getJsScore(studentList); // -> [7, 6, 8]
Oh, looks good. But I do not know who each scores belongs to.
const jsScoreDetail = R.converge(R.zipObj, [getListName, getJsScore]);
jsScoreDetail(studentList); // -> {"Cat": 6, "Dog": 7, "Mouse": 8}
Tell me their GPA
const getGPA = R.composeK(
R.map(R.mean, R.values),
getScore,
);
const getStudentGPA = R.converge(R.zipObj, [getListName, getGPA]);
getStudentGPA(studentList); // -> {"Cat": 7, "Dog": 8, "Mouse": 9}
Conclusion
I hope the above examples bring you a feel of Ramda. I try to make them clear and easy to reason about, but still the best way is to try and understand yourself how good this library is.
Some may try to compare Ramda to underscore/lodash and debate about them. For me, I think that is useless because they are all good libraries and help you to get job done. The different is that Ramda introduces and teach you to how the real FP works, that is why I really like and want to use it.
I believe library come and go but their ideas will last, so I strongly encourage you give it try.