From: Thomas A. Russ on
Zaka <shanatorio(a)gmail.com> writes:

> Here a let the code, which is less efficient because it has to
> compute the length of the string every execution of the function.
>
> (defun various-parts-st (string &rest parts)
> (let ((string-length (length string)))
> (cond
> ((null (car parts)) (list string))
> ((<= string-length (car parts)) (list string))
> (t
> (cons (subseq string 0 (car parts))
> (apply 'various-parts-st
> (cons (subseq string (car parts) string-length)
> (cdr parts))))))))

Ah, but it doesn't.
This makes use of the LABELS form to introduce a local function to
acutally do the work, and then uses a lexical binding to share the
single computation of the string length.

(defun various-parts-st (string &rest parts)
(let ((string-length (length string)))
(labels ((various-parts-helper (string &rest parts)
(cond ((null parts) (list string))
((<= string-length (car parts)) (list string))
(t (cons (subseq string 0 (car parts))
(apply #'various-parts-helper
(subseq string (car parts) string-length)
(cdr parts)))))))
(apply #'various-parts-helper string parts))))

I will also note that you can simplify the APPLY term because it can
take additional arguments before it's final list argument.

Now, one could simplify this even more (to eliminate APPLY) by changing
the &REST parameter in the internal helper to just be a list:

(defun various-parts-st (string &rest parts)
(let ((string-length (length string)))
(labels ((various-parts-helper (string parts-list)
(cond ((null parts-list) (list string))
((<= string-length (car parts-list)) (list string))
(t (cons (subseq string 0 (car parts-list))
(various-parts-helper
(subseq string (car parts-list) string-length)
(cdr parts-list)))))))
(various-parts-helper string parts))))



--
Thomas A. Russ, USC/Information Sciences Institute