DEV Community

Discussion on: Curry Functions in JavaScript

Collapse
 
jonrandy profile image
Jon Randy 🎖️ • Edited

*Curried functions

Collapse
 
anewman15 profile image
Abdullah Al Numan

I'm at odds with calling this

const createMessage = greeting => name => message => `${greeting}, ${name}! ${message}`);
Enter fullscreen mode Exit fullscreen mode

a curried function. There is a currying pattern implemented in the function, but it has not been curried from any passed in function. No?

Collapse
 
peerreynders profile image
peerreynders

Haskell wiki Currying:

Currying is the process of transforming a function that takes multiple arguments in a tuple as its argument, into a function that takes just a single argument and returns another function which accepts further arguments, one by one, that the original function would receive in the rest of that tuple.

f :: a -> (b -> c) -- or simply f :: a -> b -> c
Enter fullscreen mode Exit fullscreen mode

is the curried form of

g :: (a, b) -> c
Enter fullscreen mode Exit fullscreen mode

… In Haskell, all functions are considered curried: That is, all functions in Haskell take just one argument.

Thread Thread
 
anewman15 profile image
Abdullah Al Numan

In Haskell, all functions are considered curried: That is, all functions in Haskell take just one argument.

Yes, I agree.

Currying is the process of transforming a function that takes multiple arguments in a tuple as its argument, into a function that takes just a single argument and returns another function which accepts further arguments, one by one, that the original function would receive in the rest of that tuple.

Given this notion (or definition, if that is so) of currying, are we able to say the below function is a curried function ?

const createMessage = greeting => name => message => `${greeting}, ${name}! ${message}`);
Enter fullscreen mode Exit fullscreen mode

I think it does not implement currying as a technique - as there is no transformation involved. It very well does implement currying as a pattern, if we can call it a pattern. It's just a JS function declared to return a sequence of unary functions that currying an existing function would do.

I'm talking about semantics, obviously.

I have not been able to find usage of Curry (Haskell's last name, capitalized) as a noun. I think the verb "curry" is more prevalent, takes us to the kitchen. But, for me, it makes sense to attribute the technique to the person Curry, and then derive the verb from Curry, like Curry-ing.

We could call currying a pattern, if that is accepted as so. I'd love to read if there is any historical context.

Thread Thread
 
peerreynders profile image
peerreynders • Edited

Given this notion (or definition, if that is so) of currying, are we able to say the below function is a curried function ?

According to the wiki's usage

const createMessage = greeting => name => message => `${greeting}, ${name}! ${message}`;
Enter fullscreen mode Exit fullscreen mode

is the curried form of the otherwise equivalent

const createMessage = (greeting, name, message) => `${greeting}, ${name}! ${message}`;
Enter fullscreen mode Exit fullscreen mode

I think it does not implement currying as a technique.

It isn't the result of currying, the transformation by a compiler, runtime or a library function like Rambda's curry. But it is deliberately written in a fashion where only a single argument is accepted and another single argument function is returned until all parameters are bound and the final value is returned.

So while "In JavaScript, all functions are considered curried" is clearly false, it could be argued that createMessage() has been crafted to behave in a curried fashion which is close enough for many people to refer to it as a "curried function".

The issue is that nobody uses the term "curry function". If you want to be careful you could state that "createMessage satisfies the curried form`".

Also keep in mind that in lambda calculus the author is forced to write functions in the curried form due to the constraints of lambda calculus, i.e. the author is doing the "currying" manually. So it's not too far of a stretch to state that in lambda calculus all functions have to be "curried" or that it only supports "curried functions".

In JavaScript things are a bit less clear as it doesn't support "currying" as such but it has sufficient capabilities to allow functions to be written in the curried form.

Thread Thread
 
anewman15 profile image
Abdullah Al Numan • Edited

This is really the point I am at.

Currying transformation is not happening at runtime in this example, but while we write our code. As you said earlier, it's conceptual. It's about our design thinking. Then, is currying a design pattern ? Anything concrete about that so far ?

I am aware that nobody uses "curry functions". But, I think it will make a lot of sense if currying is a accepted design pattern, rather than merely as a technique.

Thread Thread
 
peerreynders profile image
peerreynders • Edited

Software, Faster • Dan North • GOTO 2016:

"Linda Rising has my favourite description of a pattern, she says if you go up to someone to say 'Hey I've got this pattern and it's a really good idea, let me show you it' and they show you it and you go that's a really good idea then it's not a pattern, it's a really good idea.

OK, if you go up to someone you say 'Hey I've got this pattern and it's like this' and they say I thought everyone did that—then it might be a pattern.

You're naming things that you see."


Dave Thomas:

"They are treated by most developers as recipes: “I need a to implement a xxx pattern”.

But they aren’t. Instead, they are a naming system. Once you’ve written code, you can say “oh, look, that’s like a strategy pattern.” You could then refer to it as such as a short cut when talking with other developers."

[ref]


"Consequently, you'll find recurring patterns of classes and communicating objects in many object-oriented systems. These patterns solve specific design problems and make object-oriented designs more flexible, elegant, and ultimately reusable."

[Design Patterns. Elements of Reusable Object-Oriented Software, 1995; p.1]


"Idioms are low-level patterns specific to a programming language. An idiom describes how to implement particular aspects of components ot the relationships between them with the features of the given language.

In this chapter we provide an overview of the use of idioms, show they can define a programming style, and show where you can find idioms."

[Pattern-Oriented Software Architecture, A System of Patterns, Vol.1 1996; p.345]


Then, is currying a design pattern ?

In my mind no; at best it's an idiomatic practice within the context of lambda calculus. That said, it's an idiomatic practice with a name.

In terms of JavaScript I'm even reluctant to use the term "curry". Rambda gets away with it because curry() "transforms" the passed function by wrapping it inside another function which mimics curried behaviour.

Given the capabilities inherent in function expressions (including arrow function expressions), Function.prototype.apply(), Function.prototype.bind(), and Function.prototype.call() I think it makes a lot more sense to talk about the practical applications of partial application in JavaScript—but that isn't as "cool" as currying.

I am aware that nobody uses "curry functions".

The issue is in the phrasing of the title.

The segment of the audience who knows what's going on expects to see "Curried Functions in JavaScript", so the title is jarring.

The uninitiated will wonder, "What's a 'curry function'" failing to read it as "Lets curry functions in JavaScript". So the title doesn't really connect with anybody in a meaningful way.

Thread Thread
 
anewman15 profile image
Abdullah Al Numan

It's good to know that it is idiomatic after all. Related to Haskell Curry, but ironically still idiomatic.

I think I will leave the title as is, because of the depth of the discussion around it.