A cons is essentially just a struct with two fields.  In Clojure, it's sort
of like:

(defrecord Cons [car cdr])
(defn cons [x y] (Cons. x y))
(defn first [x] (:car x))
(defn rest [x] (:cdr x))

The amazing thing is that you can represent any collection of arbitrary
length, just by nesting these structs with two fields (aka "cons cells"),
e.g., (cons 1 (cons 2 (cons 3 (cons 4 empty))))

But the real magic happens in the printer, where the printer knows to
follow the chain of conses until it hits empty and print the whole thing
out as a list (1 2 3 4).

In Scheme, there's no restriction on what you can pass to cons.  So you can
perfectly legally do (cons 1 2).  How should this print?  By convention, it
prints as (1 . 2).  So that's all a dotted pair is.

Why is it used?

Well, the most common use is in map-like structures.  A map is comprised of
key-value pairs, so you might as well store these pairs as (cons key value)
rather than (cons key (cons value empty)).  The former saves you memory by
using only one cons instead of two.  The former prints as a dotted pair,
since it is not a valid list ending in empty.

Clojure uses a similar trick to save memory in key-value pairs for maps.

user=> (first {:a 1, :b 2})
[a 1]

Even though it prints like a list, this is really not a true list.  It is
Clojure's equivalent of a dotted pair, a class called MapEntry which
contains a key and a value.

user=> (type (first {:a 1, :b 2}))
clojure.lang.MapEntry

Note that you can build MapEntry structures directly and access their
components, if you want to achieve a similar effect in your own code:

user=> (clojure.lang.MapEntry :a 1)
[:a 1]   ;Prints like a list, but this is not a true list.

user=> (key (clojure.lang.MapEntry. :a 1))
:a

user=> (value (clojure.lang.MapEntry. :a 1))
1

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to