2

I ran into an example of javascript code as below and am not clear on how it works. I am used to passing functions as callbacks, but I cannot seem to grasp how

  1. the variable func could take arguments (a, b), and
  2. why the function pair would be called in that fashion.

function cons(a, b) {
    const pair = func => {
        return func(a, b);
    };
    return pair;
}

function car(pair) {
    return pair((a, b) => {
        return a;
    });
}

function cdr(pair) {
    return pair((a, b) => {
        return b;
    });
}

console.log(cons(1, 2))
//  ƒ pair(func) {return func(a, b);}
console.log(car(cons(1, 2)))
// 1
console.log(cdr(cons(1, 2)))
// 2
Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
bigmugcup
  • 1,321
  • 4
  • 15
  • 26
  • 2
    (1) is because [`pair` is a closure over `a` and `b`](https://stackoverflow.com/questions/111102/how-do-javascript-closures-work). I don't understand (2). – T.J. Crowder Mar 18 '19 at 09:00
  • seems to be a copy of TRUE, FALSE and IFELSE methods from lambda calculus. – AZ_ Mar 18 '19 at 09:29

2 Answers2

2

The variable func takes arguments a and b because they're parameters in the cons function. The function call occurs like that (I believe you're talking about a function being logged to the console) because cons returns a function, which you don't call - therefore, you pass more arguments (callback functions) like so:

function cons(a, b) {
    const pair = func => {
        return func(a, b);
    };
    return pair;
}

function car(pair) {
    return pair((a, b) => {
        return a;
    });
}

function cdr(pair) {
    return pair((a, b) => {
        return b;
    });
}

cons(1, 2)(console.log);
console.log(car(cons(1, 2)))
// 1
console.log(cdr(cons(1, 2)))
// 2
Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
  • Okay. On 1, I'm not used to passing arguments to anything that isn't defined like func(a, b), but it's good to know I can. On 2, I see... I'm just passing a callback with arguments a and b, and returns a or b as func. Makes sense now. Thanks so much! – bigmugcup Mar 18 '19 at 09:11
1

in simple words, it's all happening because of closure! you are calling a function cons which internally returns another function definition which internally refers the properties a and b which are in the scope of cons [ a parent ] function.

to add more lights, let's do some simple changes and you can see it,

function cons(a, b) {
    const pair = func => {
        console.log('a: ', a);
        console.log('b: ', b);
    };
    return pair;
}

let childFun = cons(10, 30);
console.log(childFun());

now, cons returns some function which accepts one function as a parameter and executes that function on remembered a and b. in next, you are passing that closure function car function and car function is triggering that function by passing another callback which accepts both a and b but returns just b.

and in the same way, cdr function does with b

Ravindra Thorat
  • 1,822
  • 1
  • 17
  • 24