DEV Community


Posted on • Updated on

A light library for pipe style programming

A light library for pipe style programming

Pipe style programming is a powerful tool for dealing with data processing.

Ramda is the most popular library for that.

And fp-ts also excels at that and provides many useful ADT(Algebraic Data Types).

However, they may also introduce other things you don't want.

The price of Ramda

Complex type definition.

Due to the dynamic nature of Ramda, TypeScript needs to work very hard to describe it and end up with a complex type definition.

How many times have we needed to dig into the source type definition to find out
why does type inference not work, even knowing that the logic of the code is correct?

To me, TypeScript is more of an enemy than an assistant when I use Ramda.

Ramda type definitions are fragile for several reasons:

  • pipe function is designed to accept data as the last argument. That makes type inference difficult, especially when combined with overloaded functions.
  • Currying. You can pass arguments in any way you like in Haskell. It's sweet but makes type description difficult.
  • Function overload. Almost every function in Ramda is overloaded. TypeScript has difficulty choosing the right overload in the pipe function.

The price of fp-ts

fp-ts is great but introduces many functional programming concepts that many teams are unfamiliar with.

That makes team collaboration may require too much learning cost.

pipeable-es-fns maybe another choice

pipeable-es-fns proposes another solution:

  • Embrace pipe style programming.
  • Simple type definition is easy to understand and debug.
  • It just ports ES6+ functions to curried version, that's all.

The idea of pipeable-es-fns is to introduce minimal things for adopting pipe style programming.

Instead of selling point free style or Monad to the team, it should be easier to convince a team to use the curried ES6+ function.

Design philosophy

pipeable-es-fns adopts a few design philosophies to make type and usage smooth:

  1. Just curried the ES6+ functions and try to keep others untouched.
  2. Just use the TypeScript official type definitions of ES6+ functions.
  3. Just delegate the implementation to the native ES6+ functions for avoiding runtime.
  4. Unlike Ramda, the pipe function accepts data as its first argument for better type inference.
  5. Organize the functions in a namespace rather than function overload for better type inference.
  6. Doesn't support deprecated methods intentionally.
  7. Encourage to specify the optional arguments implicitly.
  8. Encourage to use one function in one way only.

Discussion (0)