Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding Eloquent Javascript partial function

Eloquent Javascript contains the following code examples:

function map(func, array) {
  var result = [];
  forEach(array, function (element) {
    result.push(func(element));
  });
  return result;
}

function asArray(quasiArray, start) {
  var result = [];
  for (var i = (start || 0); i < quasiArray.length; i++)
    result.push(quasiArray[i]);
  return result;
}

function partial(func) {
  var fixedArgs = asArray(arguments, 1);
  return function(){
    return func.apply(null, fixedArgs.concat(asArray(arguments)));
  };
}

function square(x) {return x * x;}

console.log(map(partial(map, square), [[10, 100], [12, 16], [0, 1]]));

I understand map and asArray, but partial is confusing to me. The above call returns

[[100, 10000], [144, 256], [0, 1]]

but I don't understand how. Here are my questions:

1) In the partial definition, is the arguments variable in the first line the same as the arguments variable in the last line? If not, what are the sources for each of those arguments objects?

2) When the function call occurs on the final code line above, my understanding is that fixedArgs is bound to [square] (that is, an array containing the square function). Then concat is called on it with the 2-dimensional array. Many problems, and not the correct answer, arise from these bindings, so they can't be the correct ones. How are the variables in partial bound when it's called?

like image 400
rainbowsorbet Avatar asked Sep 01 '26 18:09

rainbowsorbet


2 Answers

1) No, they're different. arguments in the first line contains the arguments to partial. arguments in the last line contains the arguments to the anonymous function that partial returned.

2) fixedArgs contains the array [square]. Since it was created from asArray(arguments, 1), it skips argument 0, which is map, and contains all the remaining arguments.

like image 115
Barmar Avatar answered Sep 04 '26 07:09

Barmar


1) In the partial definition, is the arguments variable in the first line the same as the arguments variable in the last line? If not, what are the sources for each of those arguments objects?

No it's not. arguments is based on the current function. In the first line it's the arguments supplied to partial itself, in the third one it's the arguments applied to the function.

To quote the specification:

When control enters an execution context for function code, an arguments object is created

What we're doing here is applying the arguments supplied initially in addition to the ones supplied later on. We're concating the arguments given initially with the ones given during invocation to create a partial.

2) When the function call occurs on the final code line above, my understanding is that fixedArgs bound to [map] (that is, an array containing the map function). Then concat is called on it with the 2-dimensional array. Many problems, and not the correct answer, arise from these bindings, so they can't be the correct ones. How are the variables in partial bound when it's called?

What the code in the last line is doing is:

  • partial(map, square) - creates a function out of map that uses square as the first argument, this basically creates a function that gets an array and squares it.

  • map(result, [[10, 100], [12, 16], [0, 1]]) - this performs a mapping again. This time we map every element in the array to the function declared above. The elements in the array are arrays themselves and the function we defined above takes an array and squares all its elements so what it does is square all the elements of the internal arrays.

So we get expect to get [100,1000],...

like image 41
Benjamin Gruenbaum Avatar answered Sep 04 '26 08:09

Benjamin Gruenbaum



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!