DEV Community

[Comment from a deleted post]
Collapse
 
nhidtran profile image
nhidtran • Edited

I like how each function only takes in one argument making it easier to test. And then the aspect that curried functions won't fully evaluate until all arguments are present so you don't run into the issue of x being null/undefined or something be weird. So if one argument is not present, we can predictably say that console.log(add) will return a type Function. And then the evaluation x + y doesn't alter x or y or any part of the application state. Totally new to this, so if you have any comments around it being more/less beneficial or how it can be more beneficial
I found it useful in this use case:

const getApi = baseUrl => endpoint => cb =>
    fetch(`${baseUrl}${endpoint}`)
    .then(res => res.json())
    .then(data => cb(data))
    .catch(err => console.log('Error:', err));

const starWarsBaseUrl = "https://swapi.co/api/";
const getFromStarWars = getApi(starWarsBaseUrl);
const starWarsCharacters = getFromStarWars('people');

starWarsCharacters(data => data.results.map(person => console.log(person.name)));
Collapse
 
vonheikemen profile image
Heiker

Some of the benefits that you mention I think are more related with pure functions than currying itself. Though falsey values like null and undefined can still be a problem, if you pass undefined to getApi you probably won't get what you want.

I think currying is really helpful when you make heavy use of higher order functions. Using your example, you could take it even further with a couple of helper functions.

var map = cb => arr => arr.map(cb);
var get = prop => obj => obj[prop];

var showNames = map(compose(console.log, get('name')));

starWarsCharacters(compose(showNames, get('results')));

When writting imperative code currying is rarely used or needed. But the good thing about javascript is that you don't have to curry functions in order to take advantage of partial application, Function.bind can be quite helpful sometimes. You could write getApi like you would a normal function and still be able to create those specialized functions.

function getApi(baseUrl, endpoint, cb) {
    return fetch(`${baseUrl}${endpoint}`)
    .then(res => res.json())
    .then(data => cb(data))
    .catch(err => console.log('Error:', err)); 
}

var starWarsBaseUrl = "https://swapi.co/api/";
var getFromStarWars = getApi.bind(null, starWarsBaseUrl);
var starWarsCharacters = getFromStarWars.bind(null, 'people');

starWarsCharacters(data => data.results.map(person => console.log(person.name)));
 
nhidtran profile image
nhidtran

Thanks for sharing that! I've never used Function.bind and you've provided a really awesome use case for it. And I think I'm going to re-use that implementation for the curried function in another project.