1

I'm new to functional programming and I'm trying to learn it in javascript. I found some examples and wrote my own snippet, but I don't understand WHY it works. There is a function called whatTheHeckIsThis. Can someone tell me what it is doing or what its purpose is? Note that when running this code, the output is true.

function boolFlipper(someFn){
    return function whatTheHeckIsThis(x,y){
        return !someFn(x,y);
    };
}

var checkStrings = function(x, y){
    return x === y;
}

var flipperTester = boolFlipper(checkStrings);

var str1 = "this string";
var str2 = "that string";

console.log(flipperTester(str1, str2));

My confusion is why can't I just do this instead:

function boolFlipper(someFn){ 
    return !someFn(x,y); 
} 
Accribus
  • 150
  • 14
  • 1
    So apart from the unnecessary expletives, which bit is confusing you? – UnholySheep Oct 24 '16 at 20:16
  • 1
    Do you know what `!` does? If you know the basics of functional programming, then it should be obvious how this affects the function. – Barmar Oct 24 '16 at 20:16
  • I think my question is why can't I just do this instead: function boolFlipper(someFn){ return !someFn(x,y); } – Accribus Oct 24 '16 at 20:17
  • 3
    Because that doesn't return a new function, it just calls the function once. That's the essence of higher-order function programming. – Barmar Oct 24 '16 at 20:18
  • 3
    @Accribus Where do `x` and `y` come from in that function? – Barmar Oct 24 '16 at 20:19
  • @Barmar That is part of my question. I got this snippet to work based on other code I've seen. But I don't get why it works. I'm passing values to flipperTester but how does the checkStrings function get access to them? – Accribus Oct 24 '16 at 20:22
  • 1
    See http://stackoverflow.com/questions/111102/how-do-javascript-closures-work?rq=1. – Fengyang Wang Oct 24 '16 at 20:25
  • @Accribus You're calling `someFn` with the values, and `someFn` is the `checkStrings` function you passed in to create the `flippedTester`. – Bergi Oct 24 '16 at 20:25

4 Answers4

1

a reference to whatTheHeckIsthis() will be returned and stored into flipperTester

After this, flipperTester can be used like a function.

You can use this language feature to abstract some code.

Simple example:

function addTen(x) { return x + 10 }
function multiplyByTen(x) { return x * 10 }

...

var doMath

// somewhere a user selected something
if (userInputSaysAdd) doMath = addTen
if (userInputSaysMultiply) doMath = multiplyByTen

// this will be the choosen function
doMath(someValue)
K..
  • 4,044
  • 6
  • 40
  • 85
1

Your second version doesn't work for 2 reasons:

  1. The purpose of boolFlipper is to return a new function, which you can assign to another variable and later call.
  2. Your function doesn't have x and y parameters.

To solve #2 you could write:

function boolFlipper(someFn, x, y) {
    return !someFn(x, y);
}

You would then have to call it like:

console.log(boolFlipper(checkStrings, str1, str2));

But you still couldn't do:

flipperTester = boolFlipper(checkStrings);

The original snippet returns a closure, which is bound in the environment where someFn is equal to the function passed as an argument to bookFlipper(). You can then assign this function to a variable, and call it with new arguments, that are assigned to x and y, and then the the function saved in someFn() is called, the return value is negated with !, and this is returned.

For more information about closures, see How do JavaScript closures work?

Community
  • 1
  • 1
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

In JavaScript functions are objects, so you can return them. When you return a function you are getting a function object, so you can call it as any other function. For example:

function myFun() {
    return function() {
        console.log("test");
    };
}

var functionInside = myFun();
/* This is like doing:
var functionInside = function() {
    console.log("test");
};
*/

functionInside(); // This will execute the function.

Example with your code:

This variable:

var flipperTester = boolFlipper(checkStrings);

contains a function like this:

var flipperTester = function (x,y) {
    return !someFn(x,y);
}

And this is something similar to

function flipperTester(x,y) {
    return !someFn(x,y);
}

So when you do:

flipperTester(str1, str2)

You are executing that function. The variable "someFn" inside there is the function "checkStrings", because you passed it when you initialize flipperTester variable.

J. Orbe
  • 153
  • 1
  • 6
  • I'm following this example, but I'm confused about how the parameters being passed in are utilized in my example. Like @Barmar was asking... where do the X and Y come from? I know I pass them into flipperTester, but I don't see how the whatTheHeckIsThis function gets them. – Accribus Oct 24 '16 at 20:25
-1

boolFlipper is, for our purposes here, a function decorator: it takes a function and modifies it to do something else. A more instructive example might be a logging function:

var alsoLogs = f => (...args) => {
  var result = f(...args);
  console.log(result);
  return result;
};

// now we have a function that adds 2 numbers:
var add = function add(a, b) { return a + b; };

// and we want to also log the result
var addAndLog = alsoLogs(add); // addAndLog is a function, would be the whatTheHeckIsThis from your example
addAndLog(2, 3); // logs 5 to the console

If you don't understand all the ES6 syntax that's ok, just understand that alsoLogs take a function f and returns a function that does the exact same thing as f but also logs the result to the console.

Since we as programmers are lazy, we don't want to have to write functions to glue together other functions every time we want to do this, so we write a function to do it for us, compose.

So now we can just say something like:

var addAndLog = R.compose(console.log, add);
addAndLog(2, 3); // logs 5 to the console
Jared Smith
  • 19,721
  • 5
  • 45
  • 83