# Pairwise grouping of elements of a list

I want to group the elements in an arbitrary long list into pairs and implemented the following so far:

(defun group-pairwise (numbers)
"Returns a list with the elements of NUMBERS grouped in pairs."
(cond ((null numbers) nil)
((null (rest numbers)) nil)
(t (append (list (list (first numbers) (second numbers)))
(group-pairwise (rest numbers))))))


It works, i.e.

> (group-pairwise '(3 6 0))
((3 6) (6 0))


but I found (append (list (list (first numbers) (second numbers) a bit cumbersome. Is there any way to express it more elegant?

Furthermore, I want in my later code not only to return the list of pairs but to perform an action on each pair. To keep the recursion pattern unchanged I was thinking about using progn instead of append , e.g.

(defun generate-graph-of-digits%%% (numbers &optional (graph *pe79-graph*))
"Returns a graph structure of NUMBERS."
(cond ((null numbers) nil)
((null (rest numbers)) nil)
(t (progn
(add-edge-between-vertexes graph (first numbers) (second numbers))
(generate-graph-of-digits%%% (rest numbers))))))


add-edge-between-vertexes being defined in the cl-graph package.

I am unsure about the usage of progn. Is it recommended to use it here?

## 1 Answer

Much too complicated. Use MAPCAR:

(defun group-pairwise (numbers)
"Returns a list with the elements of NUMBERS grouped in pairs."
(mapcar #'list numbers (rest numbers)))


Similar:

(defun generate-graph-of-digits (numbers graph)
(mapc (lambda (a b)
(add-edge-between-vertexes graph a b))
numbers
(rest numbers)))


Such primitive recursion can be replaced with mapping functions. Bonus: mapping functions are not limited by recursion stack.

Style

Also:

(append (list (list a b)) some-list)


is

(cons (list a b) some-list)


Then:

(cond (a (progn b c d))
((evenp n) (progn o p q))
(t (progn e f g)))


is:

(cond (a b c d)
((evenp n) o p q)
(t e f g))


Each cond clause accepts any number of Lisp forms after the condition.