The FP paradigm has a lot of terms which get thrown about which might need clarification, so use this listing. Additionally, you can link to any valid defintion with `/glossary/<term>`

, e.g. `open.sorcerers.dev/glossary/function`

A relationship or expression involving one or more variables.

```
const a = () => `hip arrow function`
const b = function () { return `assigned anonymous function` }
function c() { return `named function` }
```

The number of parameters a function takes.

```
// each of these is a number in ordinal form
const nullary = () => {}
const unary = x => x
const binary = (a, b) => [a, b]
const ternary = (a, b, c) => ({a, b, c})
const quaternary = (a, b, c, d) => "the name of 5 parameters is toomanyary"
```

A function which takes zero parameters, or is said to have an arity of 0.

`const nullary = () => `nothing``

A function which takes one parameter, or is said to have an arity of 1.

`const unary = thing => `one ${thing}``

A function which takes two parameters, or is said to have an arity of 2.

```
const binary = (thing1, thing2) => `${thing1} => ${thing2}`
const binaryMC = thing1 => thing2 => `${thing1} => ${thing2}`
const binaryC = curry((thing1, thing2) => `${thing1} => ${thing2}`)
```

A function which takes three parameters, or is said to have an arity of 3.

```
const ternary = (a, b, c) => a + b + c
const ternaryMC = a => b => c => a + b + c
const ternaryC = curry((a, b, c) => a + b + c)
```

A pure function is deterministic, has no side-effects and is referentially transparent.

```
const add = curry((a, b) => a + b)
const addTwo = add(2)
addTwo(100) / add(200)(111)
(2+100) / (200+111)
102 / 311
```

A function which will always return the same output given the same input. As a feature of this, these functions are referentially transparent:

```
import {curry} from 'ramda'
const times = curry((a, b) => a * b)
const twice = times(2)
const doubleAll = map(twice)
doubleAll([123,345,567]) === [246, 690, 1134]
// you can then work backwards from this:
map(twice)([123,345,567]) === [246, 690, 1134]
map(times(2))([123,345,567]) === [246, 690, 1134]
[
times(2)(123),
times(2)(345),
times(2)(567)
] === [246, 690, 1134]
```

That was a simple example but this maxim holds true no matter how complex the nested complexity gets. See this review for more examples.

A function which (when invoked with all inputs) can be replaced in all instances without changing the program's behavior.

```
const times = a => b => a * b
const double = times(2)
const ten = double(5)
const four = double(2)
const forty = times(ten)(four)
times(ten)(four) === times(times(2)(5))(times(2)(2))
// === times(2 * 5)(2 * 2)
// === 2 * 5 * 2 * 2
```

A side-effect is something which is external to the body of the current function (often in the form of a function call whose value is not captured).

```
const whatever = () => {
console.log('a log is a side-effect')
return Math.random() * 200
}
```

A free-variable is a global variable or variable defined externally to the function.

```
// window is a free variable with respect to `save`
const save = data => window.localStorage.setItem('saved', data)
```

You can use the free-variable partial-application pattern to fix this problem and turn this function pure:

```
const checkWindowExists = () => typeof window !== 'undefined'
const saveWithContext = fn => data => fn('saved', data)
// [...]
if (checkWindowExists()) {
const save = saveWithContext(window.localStorage.setItem.bind(window.localStorage))
}
```

If the above seems overkill, or needless, just remember that a runtime error can crash everything in JS land and a free benefit of the pattern is that you get the ability to inject mocks into your tests (e.g. `const save = saveWithContext(jest.fn())`

for instance). So pick your battles.

A function which takes a function and possible additional parameters, and returns a function.

```
const map = fn => xs => xs.map(x => fn(x))
// import {map} from 'ramda'
map(times(2))([1,2,3]) === [2,4,6]
```

Currying is a way of modifying a given function which takes multiple arguments in to a sequence of unary functions.

Specifically, in JS, it means that you can manipulate arguments, their order, and other facets of a passed in function.

```
const manual = a => b => c => a + b / c
import {curry} from 'ramda'
const auto = curry((a, b, c) => a + b / c)
manual(1)(9)(2) === auto(1)(9)(2)
manual(1)(9)(2) === auto(1, 9)(2)
manual(1)(9)(2) === auto(1, 9, 2)
manual(1)(9)(2) === auto(1)(9, 2)
```

An operation which takes two or more functions and returns a unary function.

Function composition facilitates code re-use.

```
const f = x => x
const g = x => y
const h = x => f(g(x))
// or, es6 style:
import { pipe } from 'ramda'
const h = pipe(f, g)
// if you need to roll your own
const pipe = (...fns) => (
x => fns.reduce(
(prev, fn) => fn(prev),
x
)
)
```

A combinator is a primitive higher-order function without free-variables.

```
// identity combinator
const I = x => x
// constant combinator
const K = x => () => x
// apply combinator
const A = f => x => f(x)
// thrush combinator
const T = x => f => f(x)
// duplication combinator
const W = f => x => f(x)(x)
// flip combinator
const C = f => y => x => f(x)(y)
// compose combinator
const B = f => g => x => f(g(x))
// amalgamation combinator
const S = f => g => x => f(x)(g(x))
// psi combinator
const P = f => g => x => y => f(g(x))(g(y))
// fixed-point Y combinator
const Y = f => (g => g(g))(g => f(x => g(g)(x)))
// morphisms
S(K)(K) === I
C(A) === T
W(T)(I) === I
C(W(K)(T)) === A
S(K)(A) === A
```

Often if you can identify combinators in your code, you can use them to simplify logical parts of the code because of a knowledge of certain morphisms.

Read much more on wikipedia. (The above definitions provided by this gist.)

(A common reference is To Mock A Mockingbird but your mileage may vary.)

There's a lot more to read about but one of the reasons it's cool is that using just `S`

and `K`

above, you can define a Turing complete language.

The `constant`

function takes what it is given and returns a nullary function which returns the original value. Sometimes called `always`

or the `K`

combinator.

```
const K = x => () => x
// import { always as K } from 'ramda'
const alwaysCool = K('cool')
alwaysCool() === 'cool'
```

The identity function returns what it is given. Sometimes referenced as the `I`

combinator.

```
const I = x => x
// import { identity as I } from 'ramda'
'so\n\n\n\n\nso\n\n\ncool'.split('\n').filter(I)
```

See this page on Github

Created with Gatsby using the 😎 foresight starter