Currying and Partial Functions (js)

ref – https://hackernoon.com/currying-in-js-d9ddc64f162e
https://codeburst.io/currying-in-javascript-ba51eb9778dc
https://blog.bitsrc.io/understanding-currying-in-javascript-ceb2188c339
https://dev.to/damcosset/higher-order-functions-in-javascript-4j8b

Kyle Simpsons – Functional Programming

Arity
Higher Order functions.
Closure

Curry – the process (implementing) of taking in a function with multiple parameters and creating unary (takes in 1 parameter) closures/functions.

Partial App – is applying the params and actually using the app.

Partial Functions

ref – https://medium.com/@JosephJnk/partial-function-application-in-javascript-and-flow-7f3ca87074fe

Partial application is the act of taking a function which takes multiple arguments, and “locking in” some of those arguments, producing a function which takes fewer arguments. For instance, say we have this function:

‘square’ is partial application: we create square by making a new function, which just passes its arguments through to another function, adding some hard-coded arguments to that other function.

Partial application transforms a function into another function with smaller arity.

where arity means the number of arguments a function takes.

Currying

Named after Haskell Brooks Curry, currying is the process of breaking down a function into a series of functions that each take a single argument. In other words, Currying is a technique of evaluating function with multiple arguments, into sequences of function with single argument.

In other words, when a function, instead of taking all arguments at one time, takes argument one and returns a new function. that takes argument two and returns a new function which takes the third one, and so forth, until all arguments have been fulfilled.

That is, when we turn a function call add(1,2,3) into add(1)(2)(3) . By using this technique, the little piece can be configured and reused with ease.

A curried function is a function that takes multiple arguments one at a time. Given a function with 3 parameters, the curried version will take argument one and return a function that takes argument two. It then returns a function that takes the third argument. The last function returns the result of applying the function to all of its arguments.

Why it’s useful ?

Currying helps you to avoid passing the same variable again and again.
It helps to create a higher order function. It’s extremely helpful in event handling.
Little pieces can be configured and reused with ease.

Currying example

Here’s a simple example. We’ll write a function sum3 takes three numbers and returns their sum.

In a standard way, the function is implemented like so:

However, if we provide too few parameters, or too many parameters, then it can have unintended consequences.

add(1,2) –> NaN
add(1,2,3,4) –> 6 //Extra parameters will be ignored.

The curried version of sum3 behaves a differently. It accepts one argument and returns one function. The returned function also accepts one argument and also returns another function that also accepts one argument and …

This cycle continues until the returned function accepts the last argument. The last one in the chain, finally returns the sum.

This works because JS supports closures.

Currying is a transform that makes f(a,b,c) callable as f(a)(b)(c). JavaScript implementations usually both keep the function callable normally and return the partial if arguments count is not enough.

Another example of why currying is useful

Of course, currying comes in handy when you want to:

1. Write little code modules that can be reused and configured with ease, much like what we do with npm:

For example, you own a store🏠 and you want to give 10%💵 discount to your fav customers:

When a fav customer buys a good worth of $500, you give him:

You see that in the long run, we would find ourselves calculating discount with 10% on a daily basis.

We can curry the discount function, so we don’t always add the 0.10 discount:

Now, we can now calculate only with price of the goods bought by your fav customers:

Again, it happens that, some fav customers are more important than some fav customers- let’s call them super-fav customers. And we want to give 20% discount to our super-fav customers.

We use our curried discount function:

We setup a new function for our super-fav customers by calling the curry function discount with a 0.2 value , that is 20%.

The returned function twentyPercentDiscount will be used to calculate discounts for our super-fav customers:

2. Avoid frequently calling a function with the same argument:

For example, we have a function to calculate the volume of a cylinder:

To resolve this, you curry the volume function(like we did earlier):

We can define a specific function for a particular cylinder height:

More Example

How does Curry work?

Currying works by natural closure.The closure created by the nested functions to retain access to each of the arguments.So inner function have access to all arguments.

Additional Examples

ref – https://www.sitepoint.com/currying-in-functional-javascript/

You can see how powerful this approach is, especially if you need to create a lot of very detailed custom functions.
The only problem is the syntax. As you build these curried functions up, you need to keep nesting returned functions,
and call them with new functions that require multiple sets of parentheses, each containing its own isolated argument.
It can get messy.

To address that problem, one approach is to create a quick and dirty currying function that will take
the name of an existing function that was written without all the nested returns.
A currying function would need to pull out the list of arguments for that function,
and use those to return a curried version of the original function:

Currying is an incredibly useful technique from functional JavaScript.
It allows you to generate a library of small, easily configured functions that behave consistently,
are quick to use, and that can be understood when reading your code. Adding currying to your coding practice
will encourage the use of partially applied functions throughout your code, avoiding a lot of potential repetition,
and may help get you into better habits about naming and dealing with function arguments.

Higher Order function

A higher order function is a function that takes a function as an argument, or returns a function.

One of the great advantages of using higher order functions when we can is composition.

We can create smaller functions that only take care of one piece of logic. Then, we compose more complex functions by using different smaller functions.

This technique reduces bugs and makes our code easier to read and understand.

By learning to use higher-order functions, you can start writing better code.

First we see an array of students:

Let’s write functions:

note, interface for reduce:

function(total,currentValue, index,arr) Required.
A function to be run for each element in the array.

Function arguments:

total Required. The initialValue, or the previously returned value of the function
currentValue Required. The value of the current element
index Optional. The array index of the current element
arr Optional. The array object the current element belongs to

Then insert other functions into function average. It helps you get the average of boy’s grades, and girls grades, and everyone’s grades.
Hence as you can see, its composition.

udemy example

Given function ffn that adds three args.

We create a curry function that will will spit back a closure with a function reference in it depending on whether you keep executing the curried function.

It will be used like this:

Let’s break it down.

We start off with

Which dictates the function and the # of args. The # of args will be matched later as each arg is executed during the curry. Hence, take note of arity

Now we create an IIFE that executes right away. This gives prevArgs to whatever is inside. If we decide to return a function that is inside, then that function has access to prevArgs.

Why do we do this? Because we want to get the previous args. Initially, we start off with empty array [].

curried is a function reference, so we need to execute and pass in a parameter. After we pass it in, we will be able to see the full args list.

For example curry(10)(14).

We have empty array to start when we execute curry. Then we return a function reference curried,
curry(10)(14), in which we put 10.

Now, we have

the # of args !== arity yet, so we keep going.
We create another closure with IIFE with the args list. We return a function reference curried,
curry(10)(14), in which we put 14.

Now, we have

so on and so forth…

Finally, when the # of args we input matches that of arity, we execute fn, which is the original function.

Source