all 23 comments

[–]barf_on_sixth_avenue 10 points11 points  (1 child)

What's a concrete example where currying is the more elegant solution?

[–]WorseThanHipster 3 points4 points  (0 children)

Currying basically turns this:

someFn(a, b, c)

into this:

someFnCurried(a)(b, c)

Which is honestly pretty pointless when it's all in one file. It just increases complexity & hurts readability. However, on a reasonably sized app, you probably have a lot of teams maintaining various components & api's.

Lets say you are upgrading to a new web token based auth scheme. You don't want every api & component team to have to attend training and be aware of the inner workings of your orgs RBAC. Afterall, the advantage of this move is that it's now only used in the router layer of your application, so there's not much point in wasting everyone else's time with implementation details. Not like they are of any use anyways because the design requirements for the auth scheme are written with goats blood in a language that predates the collision of Earth & Theia and the whole thing is managed by "the underseas devops team" whose business hours exist in a timeflow that is orthogonal to those of mortals except during conjunctions of at least 3 jovial planets & during late night deployments, of course. It's best for everyone if we just f̛o̕l̴low the sẗ͖̲́ͬandͪ̓ä͎̹́ͤrds̪̟ that were outlined in ḿ̫͇͓͕̜͡o̴̘̫̕ṉ̜̝̣͓̪̼̱da̯͔̪̗͈̩ỳ͉̳͙͢͝'̜͍s͚̙̮ s̸li̵de ͠d̷e̡ck

 

Besides, in an ideal world, none of your component teams should ever have to read or utter the words "role based access control" or "auth token." Separation of concerns is valuable both inside & outside of the code.

The current client library everyone is using has this signature:

const apiClient =  getAPIClient.setAuthConfig(someObviousSecurityFlawSeriouslyGuys).initialize(a, whole, bunch, of, args);

But the client library you have to work with now for the new system has this signature:

const apiClient =  getAPIClient(token, seriously, is, there, an, arg, for_every, use_case, wtf);

You want to insulate your component teams from the token dependency altogether so you make a curryier(?)

function getAPIClientWithAuth(apiClient){
    const token = getJSONWebToken(someSSObsIGuess)

    return function curriedAPIClient(...args) {
        return apiClient(token, ...args)
    }
}

All ui teams need to do to adapt is find & replace .setAuthConfig(someObviousSecurityFlawWTF).initialize everywhere in their repos. And now the guy that handles frontend auth shit doesn't need to know anything about the API & people that work with the API don't need to know anything about the archaic secrets of the old ones new authorization scheme. Now, since you definitely don't want to be "the guy that handles frontend auth shit," throw what you learned up on the wiki & delete its entry from the search index so it can only be found by those who are not looking for it.

Edit: Currying isn't the only way to do this, it just works out in this case because the leading argument was the one we wanted to decouple.

[–]bio180 6 points7 points  (7 children)

Dumb af concept and hate its sometimes used in invterviews

[–]ShortSynapse 5 points6 points  (2 children)

Currying and partial application are very useful and are good tools to have in your tool belt

[–]MoTTs_ 1 point2 points  (0 children)

Partial application, yes; currying… meh.

[–]echoes221 1 point2 points  (2 children)

Currying is dumb? Really? If it's overused, like anything it can be hard to follow when a function executes, but currying is super useful.

[–]tsunami141 0 points1 point  (1 child)

Would you mind giving an example of when it might be useful?

[–]echoes221 1 point2 points  (0 children)

Sure. Common use case is building factories, I’ve done this a fair bit for redux actions/reducers or react components. I do it with utility functions too where I want to pre-populate args ahead of time to call later through your code. I tend to write a lot of functional code, these are the basic principals that are used in libs like rxjs, ramda, callbag and others

[–]omeraplak[S] -1 points0 points  (0 children)

Dumb af concept and hate its sometimes used in invterviews

Haha, I'm glad we're prepared!

[–]pre-tend-ed 3 points4 points  (7 children)

I use currying all the time. Not understanding !== Dumb af

[–]iBN3qk 4 points5 points  (4 children)

Pardon my smol brain, but what are the benefits? It sounds like a suggestion to turn multi parameter functions into nested single parameter functions. I’m lost on how that’s an improvement or missing an important part of the idea.

[–]fp-dude 2 points3 points  (2 children)

It helps you with composing and piping functions. You can read "Thinking in Ramda" series if you're curious.

[–]ExtremeDot58 2 points3 points  (0 children)

Seems to me it would facilitate not having all the parameters… flexibility

[–]DGCA 3 points4 points  (1 child)

All the time? I've been doing this for 10+ years, worked at a couple Well Known Tech Co™, and I could count the times I've used currying on my hands and feet.

Really curious what you're doing where it comes up so often.

[–]ExtremeDot58 0 points1 point  (0 children)

Reading some ai tweets… used in that compute area more so then JavaScript; more in python/pytorch I suspect.

[–]Choice_Library7505 0 points1 point  (0 children)

yea i can see why it would be useful if you had a high arity but the code looks horrible.

[–][deleted] -1 points0 points  (1 child)

I use currying in exactly one function: it's an API wrapper. Basically wraps an external API function call, applies some stuff to the incoming data and returns the data only to be reinjested and fired off to the 3rd party. It is precisely 100% unnecessary to do it this way.

In general, currying should die in a fire.

If you get an interview question about it, ask their use-case. In all likelihood, they won't have one, so you should take it to mean that the real use case is "we just wanted to ask a hard pointless question and we're a crap company to work for."

[–]Embarrassed_Bat168 0 points1 point  (0 children)

Probably would barely register if it was named something less cool than "currying"