Here are five different implementations of the same floorSqrt()
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:
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.
map
function. This works fairly well, but it is not mathematically correct.compose()
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.compose()
function in reverse sequence, which is just as valid.