A **function** is a *set of statements* that *performs a task* or *calculates a value*.

📦 Node.js,
🌐 Web,
📜 Files,
📰 JSDoc,
📘 Wiki.

Functions are one of the fundamental building blocks in JavaScript. It is
similar to a procedure—a set of statements that performs a task or calculates a
value (1). It can accept some **parameters**, and may define some **local**
**variables** necessary for performing the desired *operation*. These
*parameters* and *local variables* are contained in the **scope of the**
**function**, and *cannot* be accessed from the *outside*. However, a function can
access variables *external to itself* (as long as they are not *overridden*),
such as *global variables* or *variables* in the scope this function is
*encapsulated in*. A **nested function** can access *free variables* that
are defined in *outer scopes*, even when it is being *invoked* **away** from
where it is *defined*. It does this by **capturing** the *free variables* (by
*reference*) into a **closure** (1). *Closure*, *arrow functions*, and more,
are *functional language features* based on lambda calculus.

This package includes a number of methods to *transform functions*. This enables
you to obtain a desired function by transforming the behavior of existing
functions (*without actually executing them*). The **result** of a function can
be manipulated with negate. In case a *pure* function is expensive, its
results can **cached** with memoize. **Parameters** of a function can be
manipulated with reverse, spread, unspread. reverse flips the order of
parameters, spread spreads the first array parameter of a function, and
unspread combines all parameters into the first parameter (array). If you want
some **functional** **behavior**, compose, composeRight, curry, and
curryRight can be used. composeRight is also known as pipe-forward
operator or function chaining. If you are unfamiliar, Haskell is a great
purely functional language, and there is great haskell beginner guide to learn
from.

To control invocation **time** of a function, use delay. A function can be
**rate controlled** with restrict, debounce, debounceEarly, throttle,
throttleEarly. debounce and debounceEarly prevent the invocation of a
function during **hot** periods (when there are too many calls), and can be used
for example to issue AJAX request after user input has stopped (for certain
delay time). throttle and throttleEarly can be used to limit the rate of
invocation of a function, and can be used for example to minimize system usage
when a user is constantly refreshing a webpage. Except restrict, all
*rate/time control* methods can be *flushed* (`flush()`

) to invoke the target
function immediately, or *cleared* (`clear()`

) to disable invocation of the
target function.

In addition, is, isAsync, isGenerator, name, and length obtain
metadata (about) information on a function. To attach a `this`

to a function,
use bind. A few generic functions are also included: NOOP, FALSE, TRUE,
IDENTITY, COMPARE, ARGUMENTS.

This package is available in *Node.js* and *Web* formats. To use it on the web,
simply use the `extra_function`

global variable after loading with a `<script>`

tag from the jsDelivr CDN.

Stability: Experimental.

```
const xfunction = require('extra-function');
// import * as xfunction from "extra-function";
// import * as xfunction from "https://unpkg.com/extra-function/index.mjs"; (deno)
var a = xfunction.composeRight(x => x*x, x => x+2);
a(10);
// → 102
var a = xfunction.curry((x, y) => x+y);
a(2)(3);
// → 7
var a = xfunction.unspread(Math.max);
a([2, 3, 1]);
// → 1.25
```

## Index

Property | Description |
---|---|

NOOP | Do nothing. |

FALSE | Return false. |

TRUE | Return false. |

IDENTITY | Return the same (first) value. |

COMPARE | Compare two values. |

ARGUMENTS | Return the arguments passed as a array. |

name | Get the name of a function. |

length | Get the number of parameters of a function. |

bind | Bind this-object, and optional prefix arguments to a function. |

call | Invoke a function with specified this-object, and arguments provided individually. |

apply | Invoke a function with specified this-object, and arguments provided as an array. |

is | Check if value is a function. |

isAsync | Check if value is an async function. |

isGenerator | Check if value is a generator function. |

contextify | Contextify a function by accepting the first parameter as this-object. |

decontextify | Decontextify a function by accepting this-object as the first argument. |

negate | Generate a result-negated version of a function. |

memoize | Generate result-cached version of a function. |

reverse | Generate a parameter-reversed version of a function. |

spread | Generate a (first) parameter-spreaded version of a function. |

unspread | Generate a (first) parameter-collapsed version of a function. |

attach | Attach prefix arguments to leftmost parameters of a function. |

attachRight | Attach suffix arguments to rightmost parameters of a function. |

compose | Compose functions together, in applicative order. |

composeRight | Compose functions together, such that result is piped forward. |

curry | Generate curried version of a function. |

curryRight | Generate right-curried version of a function. |

defer | Generate deferred version of a function, that executes after the current stack has cleared. |

delay | Generate delayed version of a function. |

restrict | Generate restricted-use version of a function. |

restrictOnce | Restrict a function to be used only once. |

restrictBefore | Restrict a function to be used only upto a certain number of calls. |

restrictAfter | Restrict a function to be used only after a certain number of calls. |

debounce | Generate debounced version of a function. |

debounceEarly | Generate leading-edge debounced version of a function. |

throttle | Generate throttled version of a function. |

throttleEarly | Generate leading-edge throttled version of a function. |

## References

- MDN Web docs
- Lodash documentation
- Underscore.js documentation
- Function composition
- Debouncing and Throttling Explained Through Examples by David Corbacho
- Learn You a Haskell for Great Good!: Higher order functions by Miran Lipovaca
- How to know if a function is async?
- Check if function is a generator
- Haskell composition (.) vs F#'s pipe forward operator (|>)
- JavaScript Detect Async Function by David Walsh
- is-function package by Stephen Sugden
- is-async-function package by Jordan Harband
- is-callback-function package by Charlike Mike Reagent
- is-generator-fn package by Sindre Sorhus
- is-generator-function package by Jordan Harband
- fn-name package by Sindre Sorhus
- memoizee package by Mariusz Nowak
- memoizerific package by @thinkloop
- compose-function package by Christoph Hermann
- chain-function package by Jason Quense
- @spudly/curry package by Stephen Sorensen
- one-time package by Arnout Kazemier
- onetime package by Sindre Sorhus
- once package by Isaac Z. Schlueter
- debounce package by @component
- throttle-debounce package by Ivan Nikolić
- throttleit package by @component