;;With loop: (defun pack(lst &optional groups) (loop for el in lst for first-group = (when (equal el (caar groups)) (pop groups)) do (push (cons el first-group) groups)) (reverse groups)) ;;With recursion: (defun pack(lst &optional groups) (if (not lst) (reverse groups) (let* ((el (pop lst)) (first-group (when (equal el (caar groups)) (pop groups)))) (pack lst (cons (cons el first-group) groups))))) ;;With no mercy: (defun pack(lst &optional g) (if (not lst) (reverse g) (pack (cdr lst) (cons (cons (car lst) (when (equal (car lst) (caar g)) (pop g))) g)))))