GitXplorerGitXplorer
x

jfl

public
5 stars
0 forks
15 issues

Commits

List of commits on branch master.
Verified
313ad26c14ef569e416f4332b4b2ce4af62e6b6e

Merge pull request #14 from xixixao/dependabot/npm_and_yarn/browserslist-4.16.6

xxixixao committed 3 years ago
Verified
a771d4cbb81ab2818485e910cfeaa3262f565207

Bump browserslist from 4.12.0 to 4.16.6

ddependabot[bot] committed 3 years ago
Unverified
3a1c5e938f55f17e24ef39e859f72f869f62192e

Updated docs

xxixixao committed 4 years ago
Unverified
5456af23808340921185104ff814a9b96d51bffc

More docs for string

xxixixao committed 4 years ago
Unverified
0cc4e2acb168111526b2448f4d901ae9e2772c95

Finished map tests

xxixixao committed 4 years ago
Unverified
116ac4dd2c348d6e9a9dbad9d4f27acb3cc6823c

Finished map implementation

xxixixao committed 4 years ago

README

The README file for this repository.

JavaScript Standard Funtional Library [JFL]

This JavaScript library aims to compliment the language to provide a single dependency for writing most business logic code.

It is fully statically typed to work well with both Flow and TypeScript.

What does "Functional" mean

The major difference between JFL and built-in JavaScript is that JFL favors a functional style over object-oriented style. This means that JFL:

  • exposes functions
  • the functions are pure - they don't mutate global state
  • data is treated as immutable - functions don't mutate their arguments

Some libraries and languages that are functional include other mechanisms which JFL does not include for style reasons (explained below):

What's in it?

Collections

The basic building block of a lot of code today are collections. JFL uses the same collections that JavaScript provides:

  • Arrays
  • Sets (ordered by insertion)
  • Maps (ordered by insertion)

But unlike JavaScript, the operations that are provided treat these collections as immutable (or read-only) - which is enforced with the help of static typing.

Other utilities

Utilities for the following are included:

  • Dates & Times
  • Math
  • Regular Expressions
  • Strings

Naming

Because JFL provides utilities for existing types, it uses a naming convention to avoid masking built-in objects and functions:

  • Array → Ar
  • Collection → Cl
  • Map → Mp
  • RegExp → REx
  • Set → St
  • String → Str

Example

/// Get a set of elements from two arrays
// vanilla JS
new Set(a.concat(b));

// Lodash
_.uniq(_.concat(a, b)); // actually an Array

// JFL
import {St} from 'jfl';

St.union(a, b);

JFL is heavily inspired by the Hack Standard Library, and specifically for collections and more broadly follows this rule:

The return type of a function determines which module the function is in.

In the example above we know the result should be a Set and so we we can find the function in the St module.

More examples can be found in documentation, and in examples folder.

Principles

JFL is optimized primarily for code readability. It is not optimized for terseness, performance or space efficiency, although it strives to be as good as possible in those aspects without sacrificing readability.

As mentioned above, the library is organized in such a way that it should be easy to find the function you're looking for.

For argument order, collections always come first. This works well with Hack-style pipeline operator (available using Babel today, # is the preceding result placeholder):

list
  | Ar.map(#, x => x * x)
  | Ar.filter(#, x => x % 3 === 0)
  | Mth.sum(#)

For highly performance sensitive code you can usually use the mutable collections directly. Otherwise you can check out the alternatives to this library below.

Scope

To decide which functions are included, we use 2 main criteria:

  • The use of the function doesn't lead to hard-to-read code. This is why compose for example is not included.
  • We have data to support that the function or the pattern it abstracts is used widely (for now judged by number of occurences in the Facebook codebase).

There are many functions that are perfectly readable but are only used for a specific narrow set of scenarios. For these, we will try to link to libraries that follow the same style as JFL.

Libraries out-of-scope

simple-statistics

import * as Stats from 'simple-statistics';

const mean = Stats.geometricMean(Ar.from(numbers));

immer

Immer is great for updating nested objects and collections without mutating them (in an imperative fashion, which can be simpler).

import produce from 'immer';

const updated = produce({x: {y: [3]}}, state => {
  state.x.y[0] = 4;
});

Alternatives

If this library isn't your cup of tea you might want to check the alternatives below, sorted roughly by popularity starting with the most popular.

Name Has static interface Supports Maps & Sets Non-mutating Well-typed
Lodash
Underscore
Ramda
Sugar
Lazy
CollectJS
Sanctuary
Folktale
Mout

immutable

Immutable provides alternative implementations for collections and objects (records) which use structural sharing. They should in general use less memory, but are slower to read and write to. Being different from the built-in JavaScript data structures they might be trickier to work with.