Netstring parser in common lisp
First a few minor points:


You should give the definition of split-on-first-char since it is an important function in this context.
You should use equal instead of equalp to compare a value with a string (assuming that you cannot use string= to allow the first argument not to be a string).
The second parameter of parse-netstring could be defined as &amp;optional, so that the function could be called with only the first parameter, and the second is automatically initialized with the empty list.


Then, let’s go to the main point: your function does not check many error conditions, and this is very bad for a function like this, that could get its input from the outside of the system (for instance, from a stream or a file). So, I think that you should do much more checks, for instance:


when the string does not start with a number,
when the first string part is less than the size,
when the size is greater than the whole string, etc.


The objective is to catch all the possible errors arising from calling primitive functions.

So I propose to rewrite the function in the following way, and in rewriting it I propose also a different approach to the recursion: use an auxiliary function, and recur only on the start index of the string, this make the code simpler and avoid a lot of costly subseq calls. Moreover, working with the indexes allow to get rid of the function split-on-first-char (again, with costly subseq calls). This is made possible also by the use of parse-integer with the junk-allowed parameter, which stops on the first non-numeric character, and by the fact that parse-integer returns two values, the number (which is NIL if it is not present), and the first position after the number. Here is the function:

(defun parse-netstring (netstring &amp;optional acc)
  "recursively parses netstring of the form
   size1:string1,size2:string2,size3:string3,
   acc can be any list, or nil
   returns -&gt; (string3 string2 string1)"
  (check-type netstring string "a string")
  (check-type acc list "a list")
  (let ((end (length netstring)))
    (labels ((parse-aux (start acc)
               (if (= start end)
                   acc
                   (multiple-value-bind (string-size semicolon-position)
                       (parse-integer netstring :start start :junk-allowed t)
                     (let ((comma-position
                             (when string-size (+ string-size semicolon-position 1))))
                       (unless (and string-size
                                    (&lt; comma-position end)
                                    (&lt;= string-size end)
                                    (char= (char netstring semicolon-position) #\:)
                                    (char= (char netstring comma-position) #\,))
                         (error  'malformed-netstring-error :netstring netstring))
                       (parse-aux 
                         (1+ comma-position) 
                         (cons (subseq netstring (1+ semicolon-position) comma-position) acc)))))))
      (parse-aux 0 acc))))