Three common terms come up whenever we talk about functions: domain, range, and codomain. This post clarifies what each of those terms mean.

Before we start talking about domain and range, lets quickly recap what a function is:

A function relates each element of a set with exactly one element of another set (possibly the same set).

That is, a function relates an input to an output. *But*, not all input
values have to work, and not all output values. For example, you can
imagine a function that only works for positive numbers, or a function
that only returns natural numbers. To more clearly specify the types and
values of a functions input and output, we use the terms domain, range,
and codomain.

Speaking as simply as possible, we can define what can go into a function, and what can come out:

**domain**: what can go*into*a function**codomain**: what*may possibly come out*of a function**range**: what*actually comes out*of a function

As a concrete example, consider the simple function \(f(x) = x^2\) with the domain of only positive integers \(\{1, 2, 3, ...\} \). The range would then be \(\{1, 4, 9, ...\}\). Now consider another simple function \(g(x) = x^2\) with the domain of all integers \(\{..., -3, -2, -1, 0, 1, 2, 3, ...\}\). The range would then be \(\{0, 1, 4, 9, ...\}\). Even though the two functions perform the same operation, their different domain and ranges give them different behaviour.

The difference between domain and range are somewhat obvious, but the
difference between a codomain and range are subtle. More concretly, the
codomain is the set of values that could possibly be output, while the
range is the set of values that actually do come out. The range is
actually a *subset* of the codomain. The distinction is interesting
because sometimes we do not know the exact range of a function (say it is
sufficiently complex) but we do know the codomain (such as all real
numbers). In these cases, specifying the codomain is still useful, so we
do that.

In functional programming, the domain and range are typically specified as expected data types that are input to and returned from a function. Other than this distinction, you can treat any discussions about domain, codomain, and range using the knowledge from this post.