Is the lodash flow function a real compose function, or is it something that looks like one, but is optimized to run fast and sacrifices the flexibility I'd expect? I expected flow to return a function I could curry, but instead it gave back a function that uses Javascript's arguments keyword. So curry can't tell that there are pending arguments, and it just gets invoked immediately.
Working intuitively enough:
var add = function(x, y) {
return x + y
};
var exclam = function(x) {
return x.toString() + "!";
}
exclam(1) // "1!"
add(1,2) // 3
var add1 = FP.curry(add)(1);
add1(4) // 5
var add1AndExclam = FP.flow([add1, exclam])
add1AndExclam(2) // "3!"
Non-intuitive result:
addAndExclam = FP.flow([add, exclam])
/*
function(){
var t=arguments,e=t[0];
if(i&&1==t.length&&yi(e)&&e.length>=200)return i.plant(e).value();
for(var u=0,t=r?n[u].apply(this,t):e;++u<r;)t=n[u].call(this,t);
return t
}
*/
addAndExclam(1,2) // "3!"
add1AndExclamV2 = FP.curry(addAndExclam)(1) // "NaN!"`
Is it overkill to look for another library to help with functional programming paradigms? Should I just whip up my own compose? I used lodash because it was already in my project. The documentation makes it look like flow should be lodash's compose.
I've also found it really difficult to curry the data argument in lodash's each (I wanted something like an eachMyArrayName shortcut). Whether I use curryRight or the lodash object placeholder convention.
Is lodash FP just for making lodash functions auto curriable? Or am I doing something wrong, and it is usable as the main functional programming helper?
Edit:
If I want to I can wrap the function like this, but it seems to defeat the purpose of meta programming to have boilerplate looking code.
add1AndExclamV2 = FP.curry(function(x, y) {
return addAndExclam(x, y)
})(1)
add1AndExclamV2(2)
"3!"`
var myAdd = function(x, y) { return x + y; }; var exclam = function(x) { return x.toString() + '!'; }; var addSclam = pipe(myAdd, exclam); addSclam(1,2); // "3!" var add1Sclam = curry( addSclam )(1); add1Sclam(500); // "501!"
It looks like ramda does what would have been intuitive to me. It adds another 1.2mb to my project, but I guess it could be used to more or less replace lodash.
This is just basic function composition. Lodash "flow" and Rambda "pipe" probably found it difficult to name these functions because they're not suitably generic. They're not "real" the same way you use the word real in the phrase "real compose function".
You can compose a binary function with a unary function using
comp2
– the catch is, the "binary" function must be in curried form instead of taking a tupleinstead of
Recall that functional programming has its roots in the lambda calculus where there is no such thing as a function that takes anything other than 1 argument.
I encourage you to use the substitution model to see how the expression evaluates
Putting types on everything helps you reason about the program more effecitvely
Regarding your comment:
Good idea. If you find yourself looking around for a built-in procedure (provided by your language or some library), that should already be an indicator to you that you should try to write it out first. At least confirm with yourself that you're understanding your needs correctly.
This is perfectly acceptable
And so is this
If you later learn about
comp2
and see that it could describe the code a little better, then you can implement it at that time