### The `cons` Form

Remember how we used `cons` to "extract" head and tail values of a list when matching them? In the REPL, we would do it like so:

``````lfe> (set (cons head tail) (list 'Paris 'London 'Rome))
(Paris London Rome)
Paris
lfe> tail
(London Rome)
``````

Well, that's not how `cons` started life1; it's original use was in "cons"tructing lists, not taking them apart. Here is some classic usage:

``````lfe> (cons 'Madrid tail)
``````

Let's look at a more involved example where we use `cons`es to reverse the order of a list:

``````(defmodule tut10
(export all))

(defun reverse (list)
(reverse list '()))

(defun reverse
(('() reversed-list)
reversed-list))
``````

Then, in the REPL:

``````lfe> (c "tut10.lfe")
#(module tut10)
lfe> (tut10:reverse (list 1 2 3))
(3 2 1)
``````

Consider how `reversed-list` is built: it starts as `'()`, we then successively take off the heads of the list that was provided and add these heads to the the `reversed-list` variable, as detailed by the following:

``````(reverse (cons 1 '(2 3)) '()) => (reverse '(2 3) (cons 1 '()))
(reverse (cons 2 '(3)) '(1)) => (reverse '(3) (cons 2 '(1)))
(reverse (cons 3 '()) (2 1)) => (reverse '() (cons 3 '(2 1)))
(reverse '() '(3 2 1)) => '(3 2 1)
``````

The Erlang module `lists` contains a lot of functions for manipulating lists, for example for reversing them -- our work above was done for demonstration and pedagogical purposes. For serious applications, one should prefer functions in the Erlang standard library.2

### Processing Lists

Now lets get back to the cities and temperatures, but take a more structured approach this time. First let's convert the whole list to Celsius as follows:

``````(defmodule tut11
(export (format-temps 1)))

(defun format-temps (cities)
(->c cities))

(defun ->c
(((cons (tuple name (tuple 'F temp)) tail))
(let ((converted (tuple name (tuple 'C (/ (* (- temp 32) 5) 9)))))
(cons converted (->c tail))))
(((cons city tail))
(cons city (->c tail)))
(('())
'()))
``````

Now let's test this new function:

``````lfe> (c "tut11.lfe")
#(module tut11)
lfe> (tut11:format-temps
'(#(Moscow #(C 10))
#(Cape-Town #(F 70))
#(Stockholm #(C -4))
#(Paris #(F 28))
#(London #(F 36)))))
(#(Moscow #(C 10))
#(Cape-Town #(C 21.11111111111111))
#(Stockholm #(C -4))
#(Paris #(C -2.2222222222222223))
#(London #(C 2.2222222222222223)))
``````

Let's look at this, bit-by-bit. In the first function:

``````(defun format-temps (cities)
(->c cities))
``````

we see that `format-temps/1` calls `->c/1`. `->c/1` takes off the head of the List `cities` and converts it to Celsius if needed. The `cons` function is used to add the (maybe) newly converted city to the converted rest of the list:

``````(cons converted (->c tail))
``````

or

``````(cons city (->c tail))
``````

We go on doing this until we get to the end of the list (i.e. the list is empty):

``````  (('())
'())
``````

Now that we have converted the list, we should add a function to print it:

``````(defmodule tut12
(export (format-temps 1)))

(defun format-temps (cities)
(print-temps (->c cities)))

(defun ->c
(((cons (tuple name (tuple 'F temp)) tail))
(let ((converted (tuple name (tuple 'C (/ (* (- temp 32) 5) 9)))))
(cons converted (->c tail))))
(((cons city tail))
(cons city (->c tail)))
(('())
'()))

(defun print-temps
(((cons (tuple name (tuple 'C temp)) tail))
(io:format "~-15w ~w c~n" (list name temp))
(print-temps tail))
(('())
'ok))
``````

Let's take a look:

``````lfe> (c "tut12.lfe")
#(module tut12)
lfe> (tut12:format-temps
'(#(Moscow #(C 10))
#(Cape-Town #(F 70))
#(Stockholm #(C -4))
#(Paris #(F 28))
#(London #(F 36)))))
'Moscow'        10 c
'Cape-Town'     21.11111111111111 c
'Stockholm'     -4 c
'Paris'         -2.2222222222222223 c
'London'        2.2222222222222223 c
ok
``````

### Utility Functions Revisited

Remember a few sections back when we created the utility function for finding the maximum value in a list? Let's put that into action now: we want to add a function which finds the cities with the maximum and minimum temperatures:

``````(defun find-max-min
(((cons city tail))
(find-max-min tail city city)))

(defun find-max-min
(find-max-min tail
(('() max-city min-city)
(tuple max-city min-city)))

(defun compare-max
(((= (tuple name1 (tuple 'C temp1)) city1)
(= (tuple name2 (tuple 'C temp2)) city2))
(if (> temp1 temp2)
city1
city2)))

(defun compare-min
(((= (tuple name1 (tuple 'C temp1)) city1)
(= (tuple name2 (tuple 'C temp2)) city2))
(if (< temp1 temp2)
city1
city2)))
``````

### The Complete Example

``````(defmodule tut13
(export (format-temps 1)))

(defun format-temps (cities)
(let* ((converted (->c cities)))
(print-temps converted)
(print-max-min (find-max-min converted))))

(defun ->c
(((cons (tuple name (tuple 'F temp)) tail))
(let ((converted (tuple name (tuple 'C (/ (* (- temp 32) 5) 9)))))
(cons converted (->c tail))))
(((cons city tail))
(cons city (->c tail)))
(('())
'()))

(defun print-temps
(((cons (tuple name (tuple 'C temp)) tail))
(io:format "~-15w ~w c~n" (list name temp))
(print-temps tail))
(('())
'ok))

(defun find-max-min
(((cons city tail))
(find-max-min tail city city)))

(defun find-max-min
(find-max-min tail
(('() max-city min-city)
(tuple max-city min-city)))

(defun compare-max
(((= (tuple name1 (tuple 'C temp1)) city1)
(= (tuple name2 (tuple 'C temp2)) city2))
(if (> temp1 temp2)
city1
city2)))

(defun compare-min
(((= (tuple name1 (tuple 'C temp1)) city1)
(= (tuple name2 (tuple 'C temp2)) city2))
(if (< temp1 temp2)
city1
city2)))

(defun print-max-min
(((tuple (tuple max-name (tuple 'C max-temp))
(tuple min-name (tuple 'C min-temp))))
(io:format "Max temperature was ~w c in ~w~n" (list max-temp max-name))
(io:format "Min temperature was ~w c in ~w~n" (list min-temp min-name))))
``````

Let's try it out:

``````lfe> (c "tut13.lfe")
#(module tut13)
lfe> (tut13:format-temps
'(#(Moscow #(C 10))
#(Cape-Town #(F 70))
#(Stockholm #(C -4))
#(Paris #(F 28))
#(London #(F 36)))))
'Moscow'        10 c
'Cape-Town'     21.11111111111111 c
'Stockholm'     -4 c
'Paris'         -2.2222222222222223 c
'London'        2.2222222222222223 c
Max temperature was 21.11111111111111 c in 'Cape-Town'
Min temperature was -4 c in 'Stockholm'
ok
``````

As you may have noticed, that program isn't the most efficient way of doing this, since we walk through the list of cities four times. But it is better to first strive for clarity and correctness and to make programs efficient only if really needed.

1 Way back in the prehistoric times when large, building-size computers still roamed the earth and the languages which ran on them were tiny and furry, Lisp came along with only a handful of forms: `cons` was one of them, and it was used to construct lists, one cell at a time.

2 More information about this `lists` module is available here.