On a more theoretical side (and since I can guess where this question has arisen from), the one fundamental use of the identity functions is that they allow you to define the notion of isomorphisms, which often turn out to be a much more useful definition of "sameness" than usual equality (read this).
An isomorphism tells you that "going there and back again is the same as staying here". In set-like structures, that definition corresponds to a bijective function - but not everything is set-like. So, in general we can say: A function (morphism) f
is an isomorphism, if there is a g
(its inverse), such that f . g == id
and g . f == id
. Note that this crucially depends on having id
: we can't in general assume that things have "elements" to which we can refer to, like it us usually done when introducing bijective functions.
Here's a non set-based example: consider a directed graph. Say there are vertices A -> B
and B -> A
. Since paths can be (associatively!) concatenated, we have paths A -> B -> A
, and B -> A -> B
. But they are just "the same thing" as loops A -> A
and B -> B
(or "staying at one edge")! We now can also say that those are the identity paths for A
and B
. No bijection or "forall x in A ..." is involved at all.
All these structures can also be described (and are used) with categories in programming (Scala, Haskell); for example, pipes form a category, and thus need to have identity pipes.
And, aside, here's also another practical use, using id
as base value for a fold:
doAll = foldr (.) id [(+1), (*2), (3-)]
The short version of combining a number of endofunctions.