The procedure cons
creates a "cons cell" pointing to the two arguments provided.
A cons cell is a pair of pointers and a list is a single cons cell or a series of cons cells whose second pointer points to another cons cell, and the second pointer of the last cell points to another object .
Note: I use the word "object" for simplicity not in the programming sense.
In a proper list the second pointer of the last cons cell points to an empty list.
In an improper list the second pointer of the last cons cell points to an object that is not an empty list.
Note2: an "empty list" ()
is a unique value in scheme and is different from a list, In common lisp it is equal to nil, Nil does not exist in scheme.
+-----+-----+
| | |
| | |
+--+--+--+--+
| |
| |
v v
obj obj
A cons cell
+-----+-----+ +-----+-----+ +-----+-----+
| | +---->+ | +---->+ | |
| | | | | | | | |
+--+--+-----+ +--+--+-----+ +--+--+--+--+
| | | |
| | | |
v v v v
0 1 2 3
(0 1 2 . 3) -> (0 . (1 . (2 . 3)))
An improper list
+-----+-----+ +-----+-----+ +-----+-----+
| | +---->+ | +---->+ | +----> ()/nil
| | | | | | | | |
+--+--+-----+ +--+--+-----+ +--+--+-----+
| | |
| | |
v v v
0 1 2
(0 1 2) -> (0 . (1 . (2 . () )
A proper list
The dot (when seen in the repl) is used to signify that the final pointer of the list points to an object that is not an empty list and it is therefore an improper list.
This is my understanding at least from common lisp though I am sure it translates to most other lisps (I think Clojure is different (if you consider it a lisp that is)).
Wikipedia page on cons.
~