Seems to be pretty typical implementations of `compose` and `unfold` functions. I don't think they are optimized to be terse, but I could be wrong.
I'd love to see your "easily readable" implementation of both those functions, if you have that at hand, with the same features as the ones in the example. My guess is that your implementation will look more or less the same.
For reference (in case the website changes), this is the code we're talking about:
3 function declarations in a single line already broke my ability to parse the first line :) It's not the first time that happens to me, so I suspect that it's simply a matter that my mental push-pop stack for comprehending tightly nested code layers has a depth of just 1, or maybe 2 after a coffee...
I'd reject all 3 of these in code review. `pluckDeep` and `unfold` are basically unreadable and don't make sense without comments ("go"? this is javascript!). "Pluck deep" sounds mildly disgusting and "unfold" I guess has some analogy to folding but I couldn't tell you what it is. `compose` gets a pass because function composition is a widespread concept and the argument is `fns`, which suggests that it is indeed function composition.
You should write comments anyway, of course, but you shouldn't also punish the reader by forcing them to break out a notebook and/or reformat the code just to make it make sense. The alternating `=` and `=>` is ugly and unnecessarily difficult to follow visually. And the lines in the first two functions are too long, like writing a long forum post in one big paragraph.
Here's what I'd rather see, leaving out the mandatory JSDoc comments (caveat: JS is not my main language):
Note especially how the mostly-identical structures of the first two functions is now visually obvious, whereas before it was obfuscated. Yes, it has more words than before, but it also limits the syntax to one `=>` per line and breaks up the needlessly dense use of the conditional operator in `unfold`. It's less visually noisy specifically because we added structure.
The original version might feel elegant and efficient to some people, but to me they look like someone else's shorthand scribbles. If I am writing something for other people to read, I am going to take the time to structure it for the benefit of the reader.
That said, I don't think I've ever needed a function like `unfold` (state machine? parsing?) in a Javascript program, so I'd place extra priority on making sure the doc comment explained what it's used for, ideally with a self-contained and easy-to-understand example.
You could also rewrite `unfoldAux` to remove the explicit `func` parameter and get it from the enclosing scope; that would be fine too IMO. That's a matter of taste, depending on how much you like closures.
"But wait! It would be just as terse in any real functional programming language! You're just a bad functional programmer!"
Yeah, I probably am a bad functional programmer. But here's how I'd write `unfold` in OCaml:
let unfold func start_value =
let rec unfold_aux func curr_arg accumulator =
match func curr_arg with
| None -> accumulator
| Some (result, next_arg) -> unfold_aux func next_arg (accumulator @ [result])
in unfold_aux func start_value []
Obviously this is inefficient because `@` requires a linear scan over the data, so maybe it should be written with cons-and-reverse.
But I'd argue that the OCaml version has more or less the same structure and syntactical clarity as the Javascript version, but with the ability to take advantage of pattern matching (and taking a bit of liberty in narrowing down the opaquely truthy-or-not return value to a `None`).
As a bonus, here's a Python implementation, which uses the new structural pattern matching and looks quite a bit like the OCaml version:
def unfold(func, start_value):
def unfold_aux(func, curr_arg, accumulator):
match func(curr_arg):
case None:
return accumulator
case (result, next_arg):
return unfold_aux(func, next_arg, accumulator + [result])
return unfold_aux(func, start_value, [])
Of course, in Python nowadays I'd encourage adding type annotations, but that's another story.
Useful and clear. Love it!