Have you actually tried currying? Let's use split as an example to compare different approaches:
// This block are just the values we'll use in our examples, you can ignore themconstspaced1="hello world";constspaced2="goodbye world";constdotted1="hello.world";constdotted2="goodbye.world";constspacedArray=[...Array(10)].fill(spaced1);constdottedArray=[...Array(10)].fill(dotted2);/* Without helper functions ***************************************************/constsplitSpaced1=spaced1.split("");constsplitSpaced2=spaced2.split("");constsplitDotted1=dotted1.split(".");constsplitDotted2=dotted2.split(".");constsplitSpacedArray=spacedArray.map(spaced=>spaced.split(""));constsplitDottedArray=dottedArray.map(dotted=>dotted.split(""));/* With helper functions with no options **************************************/// More code here:constspaceSplit=string=>string.split("");constdotSplit=string=>string.split(".");// But way less code and more readability here:constsplitSpaced1=spaceSplit(spaced1);constsplitSpaced2=spaceSplit(spaced2);constsplitDotted1=dotSplit(dotted1);constsplitDotted2=dotSplit(dotted2);constsplitSpacedArray=spacedArray.map(spaceSplit);constsplitDottedArray=dottedArray.map(dotSplit);/* With helper functions with options *****************************************/// A little bit more code here:constsplit=(string,separator)=>string.split(separator);// A little bit more readability and reuse here:constspaceSplit=string=>split(string,"");constdotSplit=string=>split(split,".");// Usage is the same as above, so same benefits/* With curried functions *****************************************************/// Same amount of characters as above here:constsplit=separator=>string=>string.split(separator);// But way less code here, and even more readable:constspaceSplit=split("");constdotSplit=split(".");// Usage is almost the same as above, with extra benefits, we'll see that next
You can see you how you only write "more" if you use it once, but the power of currying comes from reuse, and that's where it becomes more readable and where you end up writing more. Keeping the examples above, let's say a new requirement appears in which some strings might come with the _ character, here's how we would solve that with each approach:
constsnakeCased="hello_world";constsnakeCasesArray=[...Array(10)].fill(snakeCased);/* Without utils **************************************************************/constsplitSnakeCasedArray=snakeCasesArray.map(snakeCased=>snakeCased.split("_"),);/* With utils without options *************************************************/// Again like before, we wrote more code (it could be less)constsnakeCaseSplit=string=>string.split("_");// But more readability and less code when usingconstsplitSnakeCasedArray=snakeCasesArray.map(snakeCaseSplit);/* With utils with options ****************************************************/// A little bit of reuse hereconstsnakeCaseSplit=string=>split("_",string);// Usage is the same as above/* Finally, with currying *****************************************************/// Way less code, and still readableconstsnakeCaseSplit=split("_");// And usage can be the same as above, but also if is only once place you could:constsplitSnakeCasedArray=snakeCasesArray.map(split("_"));
I understand that every time we do something thinking in reuse it will require a little bit more characters first, but then it requires less everywhere else. In general readability is improved because we go from stuff like this:
array.map(item=>item.split(""));
To stuff like this:
array.map(split(""));
Not to mention that map itself can be curried like this:
constmap=mapper=>array=>array.map(mapper);
And then you get even more reuse and readability:
constspaceSplit=split("");constspaceSplitMap=map(spaceSplit);spaceSplitMap(array);// And the "inline" version for single case uses:map(split(""))(array);
Currying is amazing for code size and reuse, and is very readable if we stay away from "Haskell like" practices like having single character arguments. Hope this helps see the value of currying more clearly. I was requested a few times to do a full post on the subject and I will do it soon, so I'll try to remember to let you know about it if you still don't see the value in this.
Cheers!
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
I don't see the value to use piped functions (even with pipe operator) ? It's less readable and requires more code and characters.
Have you actually tried currying? Let's use split as an example to compare different approaches:
You can see you how you only write "more" if you use it once, but the power of currying comes from reuse, and that's where it becomes more readable and where you end up writing more. Keeping the examples above, let's say a new requirement appears in which some strings might come with the
_character, here's how we would solve that with each approach:I understand that every time we do something thinking in reuse it will require a little bit more characters first, but then it requires less everywhere else. In general readability is improved because we go from stuff like this:
To stuff like this:
Not to mention that map itself can be curried like this:
And then you get even more reuse and readability:
Currying is amazing for code size and reuse, and is very readable if we stay away from "Haskell like" practices like having single character arguments. Hope this helps see the value of currying more clearly. I was requested a few times to do a full post on the subject and I will do it soon, so I'll try to remember to let you know about it if you still don't see the value in this.
Cheers!