Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
589 views
in Technique[技术] by (71.8m points)

functional programming - How to reconcile Javascript with currying and function composition

I love currying but there are a couple of reasons why a lof of Javascript devs reject this technique:

  1. aesthetic concerns about the typical curry pattern: f(x) (y) (z)
  2. concerns about performance penalties due to the increased number of function calls
  3. concerns about debugging issues because of the many nested anonymous functions
  4. concerns about readability of point-free style (currying in connection with composition)

Is there an approach that can mitigate these concerns so that my coworkers don't hate me?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Note: @ftor answered his/her own question. This is a direct companion to that answer.

You're already a genius

I think you might've re-imagined the partial function – at least, in part!

const partial = (f, ...xs) => (...ys) => f(...xs, ...ys);

and it's counter-part, partialRight

const partialRight = (f, ...xs) => (...ys) => f(...ys, ...xs);

partial takes a function, some args (xs), and always returns a function that takes some more args (ys), then applies f to (...xs, ...ys)


Initial remarks

The context of this question is set in how currying and composition can play nice with a large user base of coders. My remarks will be in the same context

  • just because a function may return a function does not mean that it is curried – tacking on a _ to signify that a function is waiting for more args is confusing. Recall that currying (or partial function application) abstracts arity, so we never know when a function call will result in the value of a computation or another function waiting to be called.

  • curry should not flip arguments; that is going to cause some serious wtf moments for your fellow coder

  • if we're going to create a wrapper for reduce, the reduceRight wrapper should be consistent – eg, your foldl uses f(acc, x, i) but your foldr uses f(x, acc, i) – this will cause a lot of pain amongst coworkers that aren't familiar with these choices

For the next section, I'm going to replace your composable with partial, remove _-suffixes, and fix the foldr wrapper


Composable functions

const partial = (f, ...xs) => (...ys) => f(...xs, ...ys);

const partialRight = (f, ...xs) => (...ys) => f(...ys, ...xs);

const comp = (f, g) => x => f(g(x));

const foldl = (f, acc, xs) => xs.reduce(f, acc);

const drop = (xs, n) => xs.slice(n);

const add = (x, y) => x + y;

const sum = partial(foldl, add, 0);

const dropAndSum = comp(sum, partialRight(drop, 1));

console.log(
  dropAndSum([1,2,3,4]) // 9
);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...