Circular List in Common Lisp

I work using a visual programming environment for CL-based music composition. I am trying to create a function that, if given, 3 elements (1 2 3) will return 1, 2, 3, 1, 2, 3, etc., One number each time for each evaluation. Common Lisp's book "Gentle Introduction" briefly mentions that you can create circular lists using clear notation, but not go into details about how to use them. Keep in mind that I can insert the actual Lisp code into the program using a specially designed object for this.

+5
lisp circular-list common-lisp
May 21 '13 at 19:54
source share
3 answers
CL-USER 3 > (defun circular (items) (setf (cdr (last items)) items) items) CIRCULAR CL-USER 4 > (setf *print-circle* t) T CL-USER 5 > (circular (list 1 2 3)) #1=(1 2 3 . #1#) 

Example:

 CL-USER 16 > (setf c1 (circular (list 1 2 3))) #1=(1 2 3 . #1#) CL-USER 17 > (pop c1) 1 CL-USER 18 > (pop c1) 2 CL-USER 19 > (pop c1) 3 CL-USER 20 > (pop c1) 1 

and

 CL-USER 6 > '#1=(1 2 3 . #1#) #1=(1 2 3 . #1#) 

With the addition of a bit of CLOS:

 (defclass circular () ((items :initarg :items))) (defmethod initialize-instance :after ((c circular) &rest initargs) (setf (slot-value c 'items) (circular (slot-value c 'items)))) (defmethod next-item ((c circular)) (prog1 (first (slot-value c 'items)) (setf (slot-value c 'items) (rest (slot-value c 'items))))) CL-USER 7 > (setf circ1 (make-instance 'circular :items (list 1 2 3))) #<CIRCULAR 40200017CB> CL-USER 8 > (next-item circ1) 1 CL-USER 9 > (next-item circ1) 2 CL-USER 10 > (next-item circ1) 3 CL-USER 11 > (next-item circ1) 1 CL-USER 12 > (next-item circ1) 2 
+10
May 22 '13 at 7:38
source share

In the designation of an even sign , it is written as #0=(1 2 3 . #0#) .

Here is a function that creates a list of the given arguments:

 (defun circular (first &rest rest) (let ((items (cons first rest))) (setf (cdr (last items)) items))) 

Then the call (circular 1 2 3) will return the list of circles you wanted. Just use car and cdr to repeat ad infinitum elements.

And if you really need an iterator function that takes no arguments and returns the next element for each call, here's how you can do it:

 (defun make-iter (list) (lambda () (pop list))) 
+8
May 21 '13 at 21:25
source share

Here is an idea developed for a circular list in Lisp.

 ;;; Showing structure of the list ;;; (next prev is-end val) ; create items setf L-0 (L-1 L-3 t "L-0 sentry") ; this will be the sentry item so know where to stop setf L-1 (L-2 L-0 nil "L-1") setf L-2 (L-3 L-1 nil "L-2") setf L-3 (L-0 L-2 nil "L-3") ; how to access L-2 from L-0 eval (first (eval (first L-0))) ; result: (L-3 L-1 NIL "L-2") 

I do not provide defun functions for adding, removing, and accessing elements. I think that what I have given is enough to show what you need to do in any functions that you define for such a circular list. It seemed to me that I work in a Listener.

0
Feb 06 '17 at 15:41
source share



All Articles