I am reading Eloquent Javascript and am having a difficult time understand the example below. Would anyone be able to do a line by line type explanation? Specifically, I'm confused as to why the first loop is starting at one, and why the push method is being used on both knownArgs and arguments. I know that this is related to "partial application", but would like a more detailed explanation of what exactly is happening line by line.
var op = {
"+": function(a,b){return a + b;}
};
function partial(func) {
var knownArgs = arguments;
return function() {
var realArgs = [];
for (var i=1; i<knownArgs.length; i++)
realArgs.push(knownArgs[i]);
for (var i=0; i<arguments.length; i++)
realArgs.push(arguments[i]);
return func.apply(null, realArgs);
};
}
map(partial(op["+"], 1), [0, 2, 4, 6, 8, 10]);
The first loop starts at one instead of zero because
knownArgs[0]
contains the function, not its argument.push
appends a single element to an array. It's a fairly common way to build an array.will create a new array concatenated from
knownArgs
andarguments
.knownArgs
holds the curried arguments and the function (which is not appended torealArgs
), andarguments
are the arguments supplied to the function when it's being called.The
knownArgs
variable keeps a copy of the value ofarguments
as it was whenpartial()
was called. That call returns another function, and inside that codearguments
are a whole different list — they're the arguments passed to that returned function. In other words:var p = partial(someFunction, "hello", "world");
When
p()
is called,knownArgs
will be "hello" and "world" (well andsomeFunction
too but note that the first loop starts at 1). If the call top()
looks like this:p("how", "are", "you");
then it will first push "hello" and "world" onto the
realArgs
list (fromknownArgs
), and then the three parameters passed top()
, fromarguments
.edit — step-by-step breakdown of how
map(partial(op["+"], 1), [0, 2, 4, 6, 8, 10]);
is evaluated:First,
op["+"]
has to be evaluated. I'm guessing it returns a function, probably something like this:That "add" function and the value
1
are passed topartial()
. Thus insidepartial()
thearguments
pseudo-array looks likeThat is, the first parameter is the "add" function from
op["+"]
and the second is that value1
. The only thing thatpartial()
really does before returning the anonymous function is to savearguments
intoknownArgs
. That has to be done because the weirdarguments
pseudo-variable is always assigned a new value upon each and every function call. It's being preserved here so that the code in the anonymous function can access it later.Now, with the anonymous function returned from
partial()
and that array of even numbers, we callmap()
. That function probably looks something like this (I don't have the book):Inside
map()
, then, the first parameter is the anonymous function returned from the earlier call topartial()
. What does that function do? Well, it combines the parameters from the originalpartial()
call — except the first one — with the parameters passed into it. Themap()
function only passes one parameter, so the resulting parameter list on each call to the anonymous function will be the value1
passed topartial()
and then, on each iteration, a different even number from the list.A simpler example would be to consider what happens when you call:
That is, if you call
partial()
and then immediately use its return value (the anonymous function). The effect will be the same as calling: