Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/xixixao/jfl
JavaScript Standard Functional Library
https://github.com/xixixao/jfl
Last synced: 8 days ago
JSON representation
JavaScript Standard Functional Library
- Host: GitHub
- URL: https://github.com/xixixao/jfl
- Owner: xixixao
- Created: 2018-03-31T18:46:53.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2023-01-06T08:17:01.000Z (about 2 years ago)
- Last Synced: 2024-11-14T20:47:48.601Z (2 months ago)
- Language: JavaScript
- Homepage: https://xixixao.github.io/jfl/
- Size: 890 KB
- Stars: 5
- Watchers: 3
- Forks: 0
- Open Issues: 15
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
Awesome Lists containing this project
README
# 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 argumentsSome libraries and languages that are functional include other mechanisms which JFL **does not** include for style reasons (explained [below](#principles)):
- [currying](https://en.wikipedia.org/wiki/Currying)
- [point-free style](https://en.wikipedia.org/wiki/Tacit_programming)## 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
```js
/// 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](/examples).
## 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):
```js
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]([#alternatives]).
## 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](https://simplestatistics.org/)
```js
import * as Stats from 'simple-statistics';const mean = Stats.geometricMean(Ar.from(numbers));
```[immer](https://immerjs.github.io/immer/)
Immer is great for updating nested objects and collections without mutating them (in an imperative fashion, which can be simpler).
```js
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](https://lodash.com/) | ✅ | ❌ | ❌ | ❌ |
| [Underscore](https://underscorejs.org/) | ✅ | ❌ | ❌ | ❌ |
| [Ramda](https://ramdajs.com/) | ✅ | ❌ | ✅ | ❌ |
| [Sugar](https://sugarjs.com/) | ✅ | ❌ | ❌ | ❌ |
| [Lazy](http://danieltao.com/lazy.js) | ❌ | ❌ | ✅ | ❌ |
| [CollectJS](https://collect.js.org/) | ✅ | ❌ | ✅ | ❌ |
| [Sanctuary](https://sanctuary.js.org/) | ✅ | ❌ | ❌ | ❌ |
| [Folktale](https://folktale.origamitower.com/) | ✅ | ❌ | ❌ | ❌ |
| [Mout](http://moutjs.com/) | ✅ | ❌ | ❌ | ❌ |---
[immutable](https://immutable-js.github.io/immutable-js/)
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.