I believe the reason for the use of both nil and null is that the
former is primarily a noun, and the latter primarily an adjective (I
checked on the web and in my paper dictionnary: American Heritage 1992).
Regarding meaning and history, NIL is a contraction from Latin "nihil"
which means "nothing".
To my knowledge, the use of the name nil
to denote a null
pointer was introduced with the programming language Lisp (1958).
A null pointer is a pointer value that is supposed to point to
nothing, and should thus not be dereferenced. In most cases, pointers
are simply memory addresses. Any variable (i.e., any location) that is
intended to contain such a pointer will always contain some
configuration of bits, and any such configuration can be read as a
memory address. Hence it is often the case that the value nil
will be
the address of a memory area that is forbidden to the program, thus
causing some form of failure (possibly interrupt) if the program
attempts to dereference nil
, which can only be an error.
Having a unique predefined standard value to play this role is
essential in languages using pointers explicitly, since it is
important to be able to test whether a pointer is atually pointing to
some memory location, or not. Typically, in Lisp, a list was built as
a succession of "cons" pairs containing a "car" pointer to a list
element and a "cdr" pointer to the next pair. In the last pair of the
list, the second pointer was nil
.
This corresponds to the recursive definition of a list as either an
empty list, or a list element concatenated to a list. Hence a list
with no element was represented by nil
. This empty list happens to
be the identity of the list monoid.
Since lists can be used to represent sets, the empty set can in that
case also be represented by nil
.
Thus nil
was historically a special pointer value, but came to be
understood as a special identity value for other more abstract
domains, such as lists or sets.
A pointer equal to nil
was a null pointer, null being a adjective
rather than a substantive (i.e. a noun).
The coordinated use of both word, as adjective and noun is quite
consistent with other practice. The qualifier null is often used for
the zero of an algebraic structure, such as the identity of a monoid:
the null element. Lists form a monoid, where the value nil is the
identity. The same is true of sets (though they form an algebra with
many more properties). One says similarly that an integer is null when it is zero.
There are lots of variations on the use of these words an others, such
as none,
depending on authors and idiosyncrasies of programming languages.
The two major connotations are, as explained above
as a standard "undefined value", actually representing the absence of any usable value.
as identity value of some domain
This shows that it is not quite accurate to assert that NIL is "a value which represents the “absence of a value", as done by Gilles in the accepted answer. It depends on the language and its uses. The programming language LISP probably introduced NIL in the programming terminology 55 years ago. In LISP, NIL
is the empty list, and can equivalently be noted ()
which is the natural representation of the empty list. It does not represent the absence of a value. It is sometimes used as place-holder for missing values, though that is often to be avoided precisely because the empty list is a value. What stands for a missing value in a structure in any arbitrary object, chosen by the programmer, that cannot be confused with acceptable values.
The two concepts are rather different, even though we have shown above that they can be related. It might be interesting to have a mode detailed taxonomie of the use of the terminology enumerated by Gilles'answer, to see whether the uses of each of these words are oriented more towards one connotation or the other.
Names are no more than what they are assigned to mean in a given
context, by whoever is defining the discourse. Some uses are more
common, more natural, or more consistent, but one should always check
for definitions and make sure what meaning was intended in each context.
And one should not always expect terminology to have been chosen with taste or consistency.