When you use `console.log` that way it gets `this` set to `null`. When you call `console.log("hello")`, `this` is set to `console`. Your code would work if you set an explicit `this`.
n.forEach(console.log.bind(console));
I don't think there's any reason for this library to exist after you understand `this` semantics but I may be missing something.
e: was, in fact, missing something. Apologies for the disparaging comment, see replies.
That's one, the other is that many of those functional methods tend to mess with functions that take more than one argument when you want to use the first one, e.g parseInt.
Convenience, I suppose; I had a few headaches when I first transitioned to Javascript and discovered the odd signatures its collection functions' callbacks are expected to have.
This is a dumb question, but I feel like maybe I'm failing to pick up on something with respect to the necessity of the count parameter. It doesn't seem like it should be necessary, but both 'butt' and your version here use it. What is it for?
It specifies how many arguments the returned function should take; in my implementation, it defaults to 1 (so you can use it like "but"), but accepts other values (so you can use it like "butt").
The reason why it's necessary to specify how many arguments are of interest is because
Of course, since this is just common or garden partial application in a language with first-class functions and a liberal attitude toward signatures, it could be trivially generalized thus:
function partial(fun) {
var applied = Array.prototype.slice.call(arguments, 1);
return function() {
var args = applied
// clone the already applied args, so we don't mistakenly modify when we...
.slice()
// ...tack on the args we received in this function's call
.concat(Array.prototype.slice.call(arguments));
return fun.apply(this, args);
};
}
var addThreeNumbers = function(a, b, c) {
return a + b + c;
};
var onePlusTheseTwo = partial(addThreeNumbers, 1);
var threePlusThisOne = partial(onePlusTheseTwo, 2);
assert(addThreeNumbers(1, 2, 3) === 6);
assert(onePlusTheseTwo(2, 3) === 6);
assert(threePlusThisOne(3) === 6);
// -> all true
It only looks like wizardry if you're not used to dealing with higher-order functions, wherein I think is meant to lie the joke, if any.
I don't encounter higher-order functions very often, and I certainly am not mentally flexible with them. Nonetheless, I have heard of partial application, yes. I understood what the count parameter was doing.
What I was having trouble understanding was why it was being used; specifically, why 'but' would have a strict arity of one in the first place, and why a second function (specifying arity) would be necessary. It doesn't follow very clearly from the examples given at all.
edit: ...was this whole thing actually a joke? I thought he was serious.
Oh! Sorry, no, that's because ECMAScript (Javascript)'s historical baggage and lax attitude toward arity produce a combinatorial explosion of stupidity.
See, you can't just
['1', '2', '3'].map(parseInt)
because:
0) All Javascript functions are variadic; the signature specified at definition time is largely advisory, and has semantic meaning only in that the language will automatically declare and bind named arguments. Arguments named in a function's signature, but not passed at call time, are undefined; arguments not named in a function's signature, but passed at call time, are not automatically bound to named variables, but can be accessed via the arguments binding, which is a unique object magically bound within a function's scope, but which will be overridden by a named argument "arguments" if one exists in the signature,
and
1) Array.map and friends pass their callbacks three arguments: the value of the element, the index of the element in the array being mapped over, and a reference to the entire array being mapped over,
and
2) Number.parseInt requires one argument, the value to cast to integer, and accepts an optional second argument, specifying a radix between 2 and 36 inclusive.
So our naïve mapping above expands to the following series of calls:
tl;dr: None of this would be necessary in a language whose collection methods did sane things. Since Javascript is not such a language, this is what we have to do.
...I'm not actually sure this whole thing was a joke, but it reads to me a little like it might've been written with the sort of smirk you tend to see academic FP purists directing at industry engineers.
20 comments
[ 2.7 ms ] story [ 65.9 ms ] threadhttps://github.com/bevacqua/butt
e: was, in fact, missing something. Apologies for the disparaging comment, see replies.
EDIT: Forgot array
but really, this library has no reason to exist
The reason why it's necessary to specify how many arguments are of interest is because
Of course, since this is just common or garden partial application in a language with first-class functions and a liberal attitude toward signatures, it could be trivially generalized thus:
It only looks like wizardry if you're not used to dealing with higher-order functions, wherein I think is meant to lie the joke, if any.What I was having trouble understanding was why it was being used; specifically, why 'but' would have a strict arity of one in the first place, and why a second function (specifying arity) would be necessary. It doesn't follow very clearly from the examples given at all.
edit: ...was this whole thing actually a joke? I thought he was serious.
See, you can't just
because:0) All Javascript functions are variadic; the signature specified at definition time is largely advisory, and has semantic meaning only in that the language will automatically declare and bind named arguments. Arguments named in a function's signature, but not passed at call time, are undefined; arguments not named in a function's signature, but passed at call time, are not automatically bound to named variables, but can be accessed via the arguments binding, which is a unique object magically bound within a function's scope, but which will be overridden by a named argument "arguments" if one exists in the signature,
and
1) Array.map and friends pass their callbacks three arguments: the value of the element, the index of the element in the array being mapped over, and a reference to the entire array being mapped over,
and
2) Number.parseInt requires one argument, the value to cast to integer, and accepts an optional second argument, specifying a radix between 2 and 36 inclusive.
So our naïve mapping above expands to the following series of calls:
tl;dr: None of this would be necessary in a language whose collection methods did sane things. Since Javascript is not such a language, this is what we have to do....I'm not actually sure this whole thing was a joke, but it reads to me a little like it might've been written with the sort of smirk you tend to see academic FP purists directing at industry engineers.