Split a list into two parts with a given length I'm learning Common Lisp as a hobby and am trying tasks from L-99: Ninety-Nine Lisp Problems, but I'm not sure how good my code is. Here is one of the tasks which I solved:

GitHub solution 

;;; (*) Split a list into two parts; the length of the first part is given.
;;; Do not use any predefined predicates.
;;;
;;; Example:
;;; * (split '(a b c d e f g h i k) 3)
;;; ((A B C) (D E F G H I K))

(defun split (given-list cnt &amp;optional (result-left nil))
  (if (= cnt 0)
    (if (null result-left)
      given-list
      (cons result-left (list given-list)))
    (if (null given-list)
      result-left
      (split (cdr given-list) (- cnt 1) (append result-left (list (car given-list)))))))
Let’s use a completely different approach: first try to solve the problem using predefined (complex) functions, then implement those functions with the primitive ones (recursion, car, cdr, etc.)

So, how could be solved your problem in Common Lisp with predefined functions? I would suggest this simple solution (note the use of values instead of list to return two different values);

CL-USER&gt; (defun split (list count)
           (values (subseq list 0 count) (nthcdr count list)))
SPLIT
CL-USER&gt; (split '(A B C D E F G) 3)
(A B C)
(D E F G)


In other words, copy the first count values from the list to a new list with subseq (reference), then simply return the elements of the list starting from count with nthcdr (reference). 

Or, if you prefer to use a single predefined function, with the following definition we make also a copy of the second part of the list (which is not strictly necessary):

(defun split (list count)
  (values (subseq list 0 count) (subseq list count)))


Now let's assume subseq it is not predefined and try to implement my-subseq with just recursion and primitive functions:

(defun copy-to-end (l end)
  "copy the list l from beginning to the element at position end - 1"
  (if (zerop end)
      nil
      (cons (car l) (copy-to-end (cdr l) (1- end)))))

(defun my-subseq (l start &amp;optional (end (length l)))
  "copy the list l from the element at position start to the element at position end - 1"
  (if (zerop start)
      (copy-to-end l end)
      (my-subseq (cdr l) (1- start) (1- end))))


So the final function will be:

(defun split (list count)
  (values (my-subseq list 0 count) (my-subseq list count)))


It is left as an exercise to define my-nthcdr with recursion and primitive functions to implement my first version of the function split.