Hello all,
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.
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.
;; 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)Last edited by garethw on , edited 1 time in total.
~garethw