esfp v0.2.0
ES Functional Programming
Improve functional programming in JavaScript
This is a Browserify transform with several features (some non-standard) to improve writing JavaScript in a functional style. This repo also serves as a place to discuss moving JavaScript in a more functional direction, and how to impliment that here.
Features
- The good ES6+ features (inspired from
es2020andes2040)- Template literals
- Arrow functions
- Block scoping
- Destructuring
- Default params
- Rest/spread
- Shorthand properties (e.g.
{ foo, bar }) - Object rest/spreads (e.g.
{ ...foo, bar: 123 })
- Non-standard features
- Pipe operator over
pull-stream - Implicit return value
- React JSX with
pragma: 'h'out-of-the-box - Static type checking with Flow
- Pipe operator over
Here is an example of piping, with implicit return, and cloning an object using spread:
function foo (options) {
options = { bar: 123, ...options }
foobar(options)
| bazqux()
| oofrab()
}Install
npm install --save esfp
# with yarn
yarn add esfpUsage
Load as a browserify transform in whatever tool you use. For example, with CLI:
browserify entry.js -g esfp > out.jsOr with browserify
b.transform('esfp')Or pull-bundle (for a more functional solution :wink:)
bundle('app.js', [ 'esfp' ])Pipe operator
To use the pipe operator, you should first be familiar with pull-stream, as it will let you do cool things like async and partial pipelines.
Here we just transform foo | bar | ... chains into pull(foo, bar, ...) calls:
values([1, 2, 3])
| map(x => x * 3)
| drain(console.log)
// into:
pull(
values([1, 2, 3])
map(x => x * 3),
drain(console.log)
)You can also create streams from other streams (known as a "partial"):
const foo =
infinity()
| map(x => x * 100)
| filter(x => x % 2)
// Use it in another pipeline:
foo | drain(console.log)See babel-plugin-pull for more details
Implicit return value
You don't need to return the last value in a function:
function foo (x) {
x % 1 !== 0
}This is especially useful in combination with the pipe operator and partial streams:
function foo ({ modifier }) {
values([ 1, 2, 3 ])
| map(x => x * modifier)
}
foo({ modifier: 3 })
| drain(console.log)See babel-plugin-implicit-return for more details
JSX pragma h
With transform-react-jsx + pragma: 'h' you have more high-level sytnax creating views with functions.
function foo (e, data) {
<div onclick=${e}>${data}</div>
}You can use this with librares like hyperapp instead of having to load babelify + the plugin.
Static type checking
This plugin automatically strips Flow types for static type checking.
Note: It does not actually check the types. Use something like ESLint for that aspect.
function foo (bar: number, baz: number): number {
return bar + baz
}This could be replaced with a more functional-style type checking:
// foo : number, number
function foo (bar, baz) {
return bar + baz
}Let me know your suggestions
Maintained by Jamen Marz (See on Twitter and GitHub for questions & updates)