# Glossary

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`

## 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` }``````

## Glossary | Arity

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"``````

## Glossary | Arity | Nullary

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

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

## Glossary | Arity | Unary

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

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

## Glossary | Arity | Binary

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}`)``````

## Glossary | Arity | Ternary

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)``````

## Glossary | Function | Purity

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

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

## Glossary | Function | Deterministic

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.

## Glossary | Function | Referential Transparency

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``````

## Glossary | Side-Effect

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
}``````

## Glossary | Function | Free-Variable

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.

## Glossary | Function | Higher-Order Function

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]``````

## Glossary | Function | Curry

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)``````

### Modules

ramdalodashkatsu-curryfpo

## Glossary | Function | Composition

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
)
)``````

## Glossary | Combinator

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.

## Glossary | Combinator | Constant

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'``````

## Glossary | Combinator | Identity

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)``````