To be fair, the g and h names should obvious to anyone who studied function composition in high school.
Also, the names you gave don't help at all, as the idea of calling those g and h is to treat them anonymously. By calling it "callTwice", you are thinking about it as some sort of utility function, which is not the case. Shows you didn't grasped the idea behind it yet.
Might be obvious to you and other FPers, but when you're trying to teach FP to programmers who may only "sort of" or "not at all" grasp FP and spend most of their daily life writing CRUD business logic apps for a living but WANT to learn more about FP in order to be better programmers then it's totally useless. I found the other example immediately more understandable - even though I personally understood the content I sympathize with the people who are struggling. The FP community needs to take the academic context out of a lot of its teaching mechanisms.
It's actually very easy to see what is happening with g and f in this example. I think the part that is pretty opaque to non-FPers is why you would want to do that. Until something clicks, it is hard to see why this construct is anything beyond a very convoluted way of calculating 3 to the fourth power.
In FP, you can treat all functions as "curryable" because that's how you achieve composition. So that would be the equivalent of naming all your functions "callTwice". Now that doesn't make sense.
Could you be a bit more specific as to what you find confusing? Is it:
- That you can use the name of a variable, h, as if it was a function? That's because Javascript has first class functions [1] - the language is defined to support passing them around as variables and calling them like that.
- That you can use h at all even though it's neither a local variable nor a parameter of the anonymous function? That's because functions in javascript aren't simply procedures in the traditional sense - i.e. description (function signature) + code - they are also closures [2]. If you declare one function inside another, it can capture (have a reference to) variables and parameters of the outer one. You are also guaranteed that local variables and parameters will not get cleaned up while a closure still exists that holds a reference to them.
OOOOOOh, ok I see how this is working a bit, I think. I am very inexperienced with Javascript, and I think I only just "got" what was being done here, so I'll try to explain my thought processes as a newbie:
So, in Javascript, variables can be functions. Which means you can pass in a function as a variable to another function. And the part that says h(h(y)), basically says that "h" has to be a function. Which means you pass in a function, and then it get's applied to itself in the way specified within that function, "g".
Another odd part is the function you pass in:
g(function(x) {
return x * x;
})(3);
because you are passing in a function, but I'd assumed that if you can only pass in one variable, and that variable has to be a function, then it seemed like you wouldn't be able to pass in an initial value for the function you want to apply. But I guess in Javascript you can pass in a value for an anonymous function defined inside a function call by using this syntax:
g(function(x) {
whatever it is that happens in this function;
})(some_value_to_be_passed_into_the_previously_defined_anonymous_function);
`g(f)` returns a function, which is then immediately called with another value. You're passing `3` to the result of `g`, not to the function you passed to `g`.
Just to help in case it isn't obvious - g also returns a function - which could be assigned to a variable. In this case it's called straight away but you could do it like
var powerOfFour = g(function(x) {return x*x;});
powerOfFour(3) === 81; //true
function g(h) { return function(y) { return h(h(y)); }; }
81 === g(function(x) { return x * x; })(3);
Specifically, why is this allowed and where can I go read about it?
return h(h(y));