tiny-cps
Tiny but powerful goodies for Continuation-Passing-Style (CPS) functions
npm install tiny-cps
No dependency policy. For maximum security, this package is intended not to have any dependencies ever.
CPS function
Any function
//cb1, cb2, ... are called any number of times with any (possibly varying each time) number of argumentsconst cpsFn = { ... }
that expects to be called with several (possibly zero) functions (callbacks) as arguments. The number of callbacks may vary each time cpsFn
is called. Once called and running, cpsFn
may call any of the callbacks cbn
any (possibly zero) number of times with any number m
of arguments (x1, ..., xm)
, where m
may also vary from call to call. The m
-tuple (vector) (x1, ..., xm)
is regarded as the output of cpsFn
passed to the n
the callback:
// (x1, ..., xm) becomes an output from the `n`th callback whenever // is called
In other words, a CPS function receives any number of callbacks that it may call in any order any number of times at any moments immediately or in the future with any number of arguments.
API in brief
const map chain filter scan CPS pipeline =
Each of the map
, chain
, filter
, scan
operators can be used in 3 ways:
// 'map' as curried functioncpsFn// 'map' method provided by the 'CPS' wrapper// 'cpsFn' is passed as value ("piped") into 'map(f)' via 'pipeline' operator
map(...functions)(cpsFunction)
cpsFn
For each n
, apply fn
to each output from the n
th callback of cpsFn
.
The result is the new CPS function that calls its n
th callback cbn
as
whenever cpsFn
calls its n
th callback.
const fs = const readFile = fs // CPS function // read file and convert all letters to uppercaseconst getCaps = // orconst getCaps = // orconst getCaps = // getCaps is a CPS function, so we just call it with any callback // => file content is capitalized and printed to console
chain(...functions)(cpsFunction)
cpsFn
where each fn
is a curried function
// fn(x1, x2, ...) is expected to return a CPS functionconst fn = { ... }
The chain
operator applies each fn
to each output from the n
th callback of cpsFn
, however, the CPS ouptup of fn
is passed ahead instead of the return value. The chain
operator returns the new CPS function newCpsFn
that calls fn(x1, x2, ...)
whenever cpsFn
passes output (x1, x2, ...)
into its n
th callback, and collects all outputs from all callbacks of all fn
s. Then for each fixed m
, outputs from the m
th callbacks of all fn
s are collected and passed into the m
th callback cbm
of newCpsFn
:
// is called whenever // is called where// cbmFn is the mth callback of fn
const writeFile = fs // CPS function const copy = // CPS function// orconst copy = // orconst copy = // copy is a CPS function, so we just call it with any callback // => file content is capitalized and printed to console
filter(...predicates)(cpsFunction)
cpsFn
where each predn
is the n
th predicate function used to filter output from the n
th callback of cpsFn
. The result is the new CPS function that calls its n
th callback cbn(x1, x2, ...)
whenever (x1, x2, ...)
is an output from the n
th callback of cpsFun
and
== true
// only copy if text is not emptyconst copyNotEmpty =
scan(...reducers)(...initialValues)(cpsFunction)
Similar to reduce
, except that all partial accumulated values are passed into callback whenever there is new output.
x1 x2 ...cpsFncpsFnx1 x2 ...x1 x2 ...
where each redn
is a reducer
// take accumulated value 'acc' and input (y1, y2, ...) and return new acc. value
const redn = (acc, y1, y2, ...) => ...
The result is the new CPS function whose output from the n
the callback is the n
th accumulated value accn
. Upon each output (y1, y2, ...)
, the new acculated value redn(accn, y1, y2, ...)
is computed and passed into the callback. The nth value xn
serves in place of acc
at the start, similar to reduce
. Note that the initial values (x1, x2, ...)
must be passed as curried arguments to avoid getting mixed with reducers.
// CPS function with 2 callbacks// each click on one of the buttons sends '1' into respective callbackconst getVotes = { upvoteButton downvoteButton }const add = acc + x// count numbers of up- and downvotes and pass into respective callbacksconst countVotes = 0 0getVotes // orconst countVotes = 0 0 // countVotes is CPS function that we can call with any pair of callbacks
More details?
This README.md
is kept minimal to reduce the package size. For more human introduction, motivation, use cases and other details, please see DOCUMENTATION.