Hacker News new | ask | show | jobs
by ufo 4155 days ago
One situation where I felt compelled to use lots of currying was when I was working with a promise library for async code. There are lots of little callbacks you need to use and you benefit from having combinators that act as function versions of js operators, like "+", "[]" and so on and currying helps cut down on the number of combinators you need.

That said, I didn't end up being a big fan of it in the end. Other people can get confused by the new abstractions the combinators introduce and whenever you pass the wrong number of arguments to a function you end up with very tricky runtime errors (this isn't an issue in Haskell because the type system checks this for you)

1 comments

That sounds like an interesting approach.

Would mind posting an example?

(I was wondering what something like Flow.js would make of the code. i.e. Could it make catching those errors easier)

Cheers.

Its been a while since I worked with this so this is kind of a shitty example out of the top of my head:

If you have code that looks like this:

    var user_list =
       fetch_json()
       .then(function(data){
           return data.users
       })
You can write it more succinctly using a combinator library instead of writing the callback out by hand:

   var user_list =
       fetch_json()
       .then(get('users'))
Similar things also apply on other code that uses callbacks like maps, filters, etc. I also had combinators for other common JS operators (set, "+", "==", ...)

The point where currying comes in is that it lets you define a single "get" function instead of a separate versions for one and two arguments:

    //curried
    x = get('users', data)
    y = get('users')(data)

    //non curried
    x = get2('users', data)
    y = get1('users')(data)
That said, there are some downsides to using combinators instead of writing the callbacks by hand. If you need to debug something the stack traces are harder to follow and currying doesn't play nice with functions like Array.prototype.forEach that pass "extra" parameters to the callbacks.

In the end the feeling I got was that trying to make JS more functional is not worth the trouble. If I could go back I would try to replace the promises with something less intrusive in terms of coding style, such as generators/coroutines.

Ah, I see.

Yes, I think I've come to the exactly same conclusions in the past, both with regard to promises and curried (or partially applied functions for that matter).

This may only apply to me but I've found that without strong, static typing to help out, my brain starts to melt sometimes trying to workout what heavily curried JS functions actual do without using a debugger.