userid1765 - 1 year ago 69

Javascript Question

I am having a hard time understanding a bit of example code from the book JavaScript Allongé.

The example code is a function for calculating the circumference for a given diameter. It shows different ways to bind values with names. One way to go about it, according to the book is this:

`(`

(diameter) =>

((PI) => diameter * PI)(3.14159265)

)(2);

// calculates circumference given diameter 2

It further states:

Well, the wrinkle with this is that typically, invoking functions is considerably more expensive than evaluating expressions. Every time we invoke the outer function, we’ll invoke the inner function. We could get around this by writing

`(`

((PI) =>

(diameter) => diameter * PI

)(3.14159265)

)(2);

I cannot understand how it gets around the situation with calling two functions, aren't there exactly two function calls in both the examples?

How do they differ from each other? Please help me get this.

Recommended for you: Get network issues from **WhatsUp Gold**. **Not end users.**

Answer Source

This probably looks a bit confusing because I don't think it's explained very well. Or, rather, I don't think it's explained in a typical JavaScript way.

Let's break down the examples

```
var calculateCircumference = (diameter) => (
(PI) => diameter * PI)(3.14159265)
);
calculateCircumference(2); // 6.2831853
```

Arranged like this, here is what happens if you call this code

- You pass the diameter (e.g., 2)
- A
*new*function is created that takes`PI`

as parameter and uses it to calculate the circumference. This function is immediately invoked - The function uses both variables present to do the calculation

Aside from being wasteful computation-wise (two invocation) this example is also convoluted for no good reason. The inner function is pointless and doesn't gain you anything. It's probably where the example loses lots of its clarity - seems like the only reason to have the example work as it is, is to set up for the second example.

Before tackling the example, it seems like the book probably failed to mention how exactly it works. The second example leverages a technique called `curry`

which is used in functional programming - it is not specific to JavaScript but it is still widely known as that name in the JavaScript world. A very brief overview of currying

```
//non-curried
function add(a, b) { // or, in ES6: (a, b) => a + b;
return a + b;
}
//curried
function curryAdd(a) { //or in ES6: (a) => (b) => a + b;
return function(b) {
return a + b;
}
}
//invocation
add(2, 3); // 5
curryAdd(2)(3); // 5
```

I will not go into detail but essentially, a curried function that takes multiple parameters, can be passed less and it will return a new function that can take the rest. When all the parameters are satisfied, you will get the result - in a formal notation, the `curryAdd`

function will be expressed as `curryAdd :: Number -> Number -> Number`

- it's a function that takes a number and returns another function that takes a number which finally returns another number. For why you would want to do that, here is an example - it's trivial but it gets the point accross:

```
//add5:: Number -> Number
add5 = curryAdd(5);
add5(3); // 8
add5(10); // 15
[1, 2, 3].map(add5); // [6, 7, 8]
```

Currying is *a bit* like partial allocation of functions but the two are not (necessarily) the same thing.

With that said, let's look at the second example:

```
//curryMultiply :: Float -> Float -> Float
(PI) => (diameter) => diameter * PI
//another way to write it:
//(a) => (b) => a * b
```

Hopefully that clarifies what is going on a bit. I'll re-write the rest of the example into what is actually happening:

```
// calculateCircumference :: Float -> Float
var calculateCircumference = curryMultiply(3.14159265);
calculateCircumference(2); //6.2831853
```

The second example's code is equivalent to the above. It avoids invoking a function twice because the *outer* function (which I dubbed `curryMultiply`

) is invoked only once - any time you call the `calculateCircumference`

function, you are only evaluating the *inner* function.

Recommended from our users: **Dynamic Network Monitoring from WhatsUp Gold from IPSwitch**. ** Free Download**