README
m
Functional library for Javascript
Changes a lot and not yet complete. Use Ramda to be safe.
Why only pipe
There is no structure difference between pipe
and compose
, both will use the same building blocks to get from A to B.
A series of transformations over an initial input can be written as
x -> f -> g -> result
, piping, or asresult = g(f(x))
, composing. The difference is only syntactic. Input is the same, transformations and order of application are the same, the result will be the same.
Syntax is the thing we look at, reason with and write ourselves everyday and is the difference between "Aah, right" and "Why is he doing -1 two times?".
There are reasons for why some use compose
notation and others pipe
. Math people will know more.
In Settings are evil, Mattias Petter Johansson makes the point of product decisions and why adding a toggle in the settings page just adds maintenance overhead and useless complexity. While a measly Twitter feature flag does not compare to Function Composition, choosing one might be helpful (just like "double quotes" over 'single quotes').
Having a set of functions/transformations/verbs, what is the best way of presenting them so that people with little to no knowledge of the overall context can understand it in the least amount of time and with smallest amount of cognitive overhead?
Given that:
- we read from left to right
- left/back is in the past, right/front is the future
- a lot of piping going on in your terminal
it makes sense to choose the syntactic more aligned with our intuition and context. The transformations are applied in a certain order with time as a medium - input -> t0 -> t1 -> tn -> output
. The way is forward.
const { sep } = require("path")
const { pipe, compose, join, push, dropLast, split } = require("@codemachiner/m")
//
// Compose - g(f(x))
//
const renameFile = newName => filePath =>
compose(
join(sep), push(newName), dropLast, split(sep)
)(filePath)
//
// Pipe - x -> f -> g
//
const renameFile = newName => filePath =>
pipe(
split(sep), dropLast, push(newName), join(sep)
)(filePath)
//
// When using the new pipeline operator, things are even more expressive
//
const renameFile = newName => filePath =>
filePath |> split(sep) |> dropLast |> push(newName) |> join(sep)
Links
Install
npm i --save-exact @codemachiner/m
Develop
git clone git@github.com:codemachiner/m.git && \
cd m && \
npm run setup
# run tests (any `*.test.js`) once
npm test
# watch `src` folder for changes and run test automatically
npm run tdd
Use
import { pipe, trim, split, dropLast, push, join } from "@codemachiner/m"
const removeTrailingSlash = source =>
source[source.length - 1] === sep ? source.slice(0, -1) : source
const renameFile = newName => pipe(
removeTrailingSlash,
split(sep),
dropLast,
push(trim(sep)(newName)),
join(sep)
)
Changelog
History of all changes in CHANGELOG.md
0.13.2 - 15 November 2018
Add
- Add
map
tests: imutable and non-array source - Add
npm audit fix
tosetup
andprepare
scripts
Change
- Change
reduce
to allow non-array input