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)))