I'm a complete CL newb, working my way through PCL, and doing some little coding projects on my own with the things I learn.

One of the hardest battles I'm fighting is trying to break the habit of trying to write things imperatively. I actually find it easier to do this in Scheme, since you really are pushed to do things recursively (I've worked my way through The Little Schemer, too). I'm still getting a feel for how to write things in idiomatic CL - I suspect I'm currently writing idiotic CL.

I was wondering if anyone would be willing to critique this little sample piece of code for overall style. It's a utility function for generating a series of lists according to a certain policy.

EDIT: This code is buggy.

- Code: Select all
`;; This one is supposed to be a bit more fair.`

;; The current "order" is defined as the largest index which is currently allowed

;; All combinations of order N are tried before any of order N+1

(defun get-next-prec-balanced (q limits)

(let ((p (copy-seq q))

(len (length q))

(order (loop for idx in q maximizing idx))) ; *FIXME* this prevents us from using arrays

(dotimes (n len)

;; If we haven't reached a hard limit or current order, increment & return

(when (< (elt p n)

(min (elt limits n) order))

(if (> order (loop for idx in p maximizing idx))

(setf (elt p n) order)

(incf (elt p n)))

(return-from get-next-prec-balanced p))

;; If we've reached the current order in the last elt, increase order

(when (and (= (elt p n) order)

(= n (- len 1)))

;; Clean all the things!

(dotimes (m len)

(setf (elt p m) 0))

;; Set the first index whose limit is < the current order to the New Order

(dotimes (m len)

(when (< order (elt limits m))

(setf (elt p 0) (+ order 1))

(return-from get-next-prec-balanced p)))

;; Order is greater than each limit; we're done

(return-from get-next-prec-balanced ()))

;; Otherwise, roll over to 0, which will carry to next position in dotimes loop

(setf (elt p n) 0))

(setf p ())

(return-from get-next-prec-balanced p)))

(If you care, the purpose of the function is to generate indices into a set of other lists. I want to iterate over permutations of the elements of each list, but rather than do it as nested loops, I want to iterate over those permutations containing the first elements in all the lists, rather than the later ones. The iteration function uses this to generate the next permutation)