DEV Community

Discussion on: The Case for TS+

mikearnaldi profile image
Michael Arnaldi Author

Lodash/Underscore are not Fluent APIs they are just modules of functions that is ok, there is a usability compromise though take for example an array "a" to map "a" you do "a.map(f)" doing "map(a, f)" isn't as nice, nor doing "pipe(a, map(f))", jQuery has a fluent api but that sort of comes from a different era and nobody is tree shaking jq. Fluent APIs cannot be tree-shaken (at all), class methods cannot be removed nor renamed, libraries like fp-ts or rx-js have moved away from those API because they aren't shakable and they aren't extensible (i.e. adding a method to a class coming from a library)

Thread Thread
jfbrennan profile image
Jordan Brennan

Curious, why would a functional programmer not want to say this counts as a fluent API:

_.chain(lyrics)
  .map(line => line.words.split(' '))
  .flatten()
  .reduce((counts, word) => {
    counts[word] = (counts[word] || 0) + 1;
    return counts;
  }, {})
  .value()
Enter fullscreen mode Exit fullscreen mode

My understanding is chaining = fluent.

Thread Thread
jfbrennan profile image
Jordan Brennan

...and importing those functions (instead of using _) makes the code tree-shakable, right?

Thread Thread
mikearnaldi profile image
Michael Arnaldi Author

Yeah, incorporating those functions (map/flatten/etc) you end up with all, for effect that can be huge there are modules with 1000+ functions

Thread Thread
patroza profile image
Patrick Roza • Edited on

@jfbrennan importing individually gains tree shaking but would mean losing chaining/fluent and therefore discoverability and usage context.

reduce(flatten(map(lyrics, line => line.words.split(' '))), (counts, word) => {
    counts[word] = (counts[word] || 0) + 1;
    return counts;
  }, {})
Enter fullscreen mode Exit fullscreen mode

or piped

pipe(
  lyrics,
  map(line => line.words.split(' ')),
  flatten,
  reduce((counts, word) => {
    counts[word] = (counts[word] || 0) + 1;
    return counts;
  }, {})
)
Enter fullscreen mode Exit fullscreen mode

With ts+ you keep chaining/fluent, discoverability and usage context, while it gets compiled down to individual imports for tree shakability and optimisations. win-win.
The bigger the library (or the more libraries), with the more type classes/modules, the more the win is.