Книга: Functional Programming in JavaScript
Назад: Compose
Дальше: Programming with compose

Compositions versus chains

Here are five different implementations of the same functional composition. They seem to be identical, but they deserve scrutiny.

function floorSqrt1(num) {   var sqrtNum = Math.sqrt(num);   var floorSqrt = Math.floor(sqrtNum);   var stringNum = String(floorSqrt);   return stringNum; }  function floorSqrt2(num) {   return String(Math.floor(Math.sqrt(num))); }  function floorSqrt3(num) {   return [num].map(Math.sqrt).map(Math.floor).toString(); } var floorSqrt4 = String.compose(Math.floor).compose(Math.sqrt); var floorSqrt5 = Math.sqrt.sequence(Math.floor).sequence(String);  // all functions can be called like this: floorSqrt<N>(17); // Returns: 4

But there are a few key differences we should go over:

  • Obviously the first method is verbose and inefficient.
  • The second method is a nice one-liner, but this approach becomes very unreadable after only a few functions are applied.

    Note

    To say that less code is better is missing the point. Code is more maintainable when the effective instructions are more concise. If you reduce the number of characters on the screen without changing the effective instructions carried out, this has the complete opposite effect—code becomes harder to understand, and decidedly less maintainable; for example, when we use nested ternary operators, or we chain several commands together on a single line. These approaches reduce the amount of 'code on the screen', but they don't reduce the number of steps actually being specified by that code. So the effect is to obfuscate and make the code harder to understand. The kind of conciseness that makes code easier to maintain is that which effectively reduces the specified instructions (for example, by using a simpler algorithm that accomplishes the same result with fewer and/or simpler steps), or when we simply replace code with a message, for instance, invoking a third-party library with a well-documented API.

  • The third approach is a chain of array functions, notably the function. This works fairly well, but it is not mathematically correct.
  • Here's our function in action. All methods are forced to be unary, pure functions that encourage the use of better, simpler, and smaller functions that do one thing and do it well.
  • The last approach uses the function in reverse sequence, which is just as valid.
Назад: Compose
Дальше: Programming with compose

bsn
thank
Vesa Karvonen
I hope you don't mind, but I’d like to point you and your readers to my high-performance optics library for JavaScript that is in production use in multiple projects, has comprehensive support for partial optics and interactive documentation: https://calmm-js.github.io/partial.lenses/ (this takes a moment to load — be patient!)