Skip to main content

Design choices

Chaining API

Most functional programming libraries in JavaScript provide a data-last API (map(func)(value)) along with a pipe function to chain operations.

While this approach works well in languages that include some kind of native pipe operator, we consider that it doesn't provide a good enough developer experience in your TypeScript code editor: it makes it tedious to inspect a value in a pipe chain and doesn't provide autocomplete natively.

For this reason, we decided to use good ol'chaining, reducing the number of imports, making your code more expressive, easier to read and inspect.

Eager over lazy

More often than not, these functional programming libraries use lazy initialisation, meaning your code won't execute until you tell it to explicitely (e.g. with a run call at the end).

In the vast majority of cases we've seen, this is not something that's wanted. For the few cases where laziness is wanted, making a function that returns the data-structure or using a Deferred does the job pretty well.

const eagerFuture = Future.make((resolve) => resolve(1));

const lazyFuture = () => Future.make((resolve) => resolve(1));

const [deferred, resolve] = Deferred.make<number>();

Naming

Rather than using naming from abstract theory, if a concept exists in JavaScript built-ins, Boxed will provide similar naming (e.g. we provide Future.all to mimic Promise.all rather than Future.sequenceArray).