1

I'm new to Javascript and Typescript and i find it incredibly difficult to understand typescript, in particularly currying functions and arrow syntax.

All this while I've been using the syntax, from Java for functions:

function(param) {
   ..dosomething..
   .
}

and starting javascript lead to arrow syntax functions which i find difficult to understand. In typescript i come across currying where i have examples shown below:

const operationOnTwoNumbers = f => x => y => f(x,y)

const multiply = operationOnTwoNumbers((x,y) => x*y)

const double = multiply(2)

[5,8,3,1,7,6,2].map(double)

I wasn't provided with a lecture of that much detail but according to my slides, it says that multiply is a curried function.

First and foremost, i want to know how do i interpret the operationOnTwoNumbers arrow syntax function. For now, i interpret it as such:

operationOnTwoNumbers is a function that takes in f as an argument, and returns a function that takes x as an argument that returns a function that takes y as an argument that returns a function that does something to x and y.

Am i correct with the interpretation? Would like some feedback on it.

Now for the multiply curried function. My interpretation would be:

multiply is a function that takes operationOnTwoNumbers as a function, that operationOnTwoNumbers take (x,y) as an argument and returns a function that multiplies x and y.

I'm pretty sure my interpretation of these are wrong in a way but i cant seem to understand the syntax. The resource I'm provided with didn't explain much and i tried googling up only to find that I'm getting more confused.

Would really appreciate some help on this, that is for my understanding.

9
  • 1
    Please note that you're not using TypeScript in the provided example - only ES6, which is basically a newer version of JavaScript. I might come up with a more detailed explanation later on when I have time. Commented Aug 9, 2018 at 12:19
  • As a JS beginner, maybe you'd be better off staying away from currying for a while. I personally think it's an rather ugly manner of dealing with functions that's difficult to maintain. Commented Aug 9, 2018 at 12:21
  • If you're not using typescript, you will get an error on your const double = multiply(2)[5,8,3,1,7,6,2].map(double) ... because it's trying to access the index of a function... and typescript does not necessarily require any type notation... Commented Aug 9, 2018 at 12:25
  • 1
    Uncaught TypeError: Cannot read property 'map' of undefined in chrome snippets... Exception: TypeError: multiply(...)[2] is undefined in Firefox scratchpad... Commented Aug 9, 2018 at 12:30
  • 1
    @CodyG. - The same problem exists in TypeScript as well. Commented Aug 9, 2018 at 12:34

1 Answer 1

2

First, let's add some missing semicolons, since without them that code fails in an obscure way (ASI won't add a ; between multiply(2) and [5,8... because taken together they're syntactically-valid, though logically nonsensical). Let's also add a console.log on the last line:

const operationOnTwoNumbers = f => x => y => f(x,y);
const multiply = operationOnTwoNumbers((x,y) => x*y);
const double = multiply(2);
console.log([5,8,3,1,7,6,2].map(double));

(You've said you're very new to JavaScript and TypeScript. I strongly recommend not relying on ASI. Put ; at the ends of all statements that aren't flow-control structures ending in blocks. So you'd have one in the places above, and you wouldn't have one on [say] a while (condition) { ... } statement.)

operationOnTwoNumbers is a function that takes in f as an argument, and returns a function that takes x as an argument that returns a function that takes y as an argument that returns a function that does something to x and y.

Am i correct with the interpretation?

Very nearly. "...that returns a function that takes y as an argument that returns a function that does something to x and y." isn't correct, it should be "...that returns the result of calling f passing in x and y." (Also, technically, f, x, and y are parameters, not argumentsÂą, but it's very common to call them arguments and you're not likely to run into much trouble doing it.) So the full explanation is: "operationOnTwoNumbers is a function that takes in f as an argument, and returns a function that takes x as an argument that returns a function that takes y as an argument that returns the result of calling f passing in x and y."

It may help to see the equivalent non-arrow version (since those functions aren't using any of the features of arrow functions other than conciseness):

const operationOnTwoNumbers = function(f) {
    return function(x) {
        return function(y) {
            return f(x,y);
        };
    };
};

multiply is a function that takes operationOnTwoNumbers as a function, that operationOnTwoNumbers take (x,y) as an argument and returns a function that multiplies x and y.

Not quite, multiply is the result of calling operationOnTwoNumbers and passing in a function, (x, y) => x * y (this becomes the f in operationOnTwoNumbers). So multiply is the function created by operationOnTwoNumbers that accepts x.

Then double is the result of calling multiply with 2, so 2 becomes x and double is the function that accepts y. So for instance, if we do double(3), then 3 is the y and since x is 2 and f is (x, y) => x * y, the result of calling double(3) is 6.

Then the map call calls double for each entry in the array, returning a new array with each value doubled.


Âą parameter vs. argument: A function declares a parameter; when you call a function, you supply an argument for that parameter. For example:

function example(v) {
    return v * 2;
}
console.log(example(7));

In example, v is a parameter (specifically a formal parameter). In the call example(7), 7 is the argument for the v parameter.

Sign up to request clarification or add additional context in comments.

3 Comments

I find myself looking at these kind of functions and wondering "whats wrong with just writing it the easily understandable/longhand way"? To quote one of (IMO) the most sensible people in computing Martin Fowler "Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
@T.J. Crowder thank you for your time typing this detailed explanation! Much appreciated. Cheers!
@Liam - Currying can be very powerful. But it's important to write it as clearly as possible, commenting it if necessary. :-)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.