Sto lavorando utilizzando un ambiente di programmazione visiva per la composizione musicale basata su CL. Sto cercando di creare una funzione che, quando viene data la risposta, 3 elementi (1 2 3) restituiranno 1, 2, 3, 1, 2, 3 ecc., Un numero alla volta ogni volta che viene valutato. Il libro Common Lisp a Gentle Introduzione, menziona brevemente che è possibile creare elenchi circolari usando la notazione sharp-equal ma non entrare nei dettagli su come usarli. Ricordare che è possibile inserire codice Lisp nel programma utilizzando un oggetto appositamente progettato per tale scopo.Elenco circolare in Common Lisp
risposta
Nella notazione Sharpsign Equal-Sign, è scritto come #0=(1 2 3 . #0#)
.
Ecco una funzione che crea una tale lista dalle argomenti dati:
(defun circular (first &rest rest)
(let ((items (cons first rest)))
(setf (cdr (last items)) items)))
Poi, chiamando (circular 1 2 3)
restituirà la lista circolare che si voleva. Basta usare car
e cdr
per scorrere gli elementi all'infinito.
E se si vuole veramente una funzione iteratore che non accetta argomenti e restituisce l'elemento successivo per ogni chiamata, ecco come si potrebbe farlo:
(defun make-iter (list)
(lambda()
(pop list)))
È possibile utilizzare PROG1 anziché LET. –
@ThomasBartscher Grazie! Ora è implementato. (In realtà ho guardato la risposta di Rainer e sembra che "pop" faccia la stessa cosa di quello che sto cercando. Ecco cosa succede quando uno Schemer tenta di scrivere CL. ;-)) –
Huh, non ci avevo pensato. Bello! –
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#)
Esempio:
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
anche:
CL-USER 6 > '#1=(1 2 3 . #1#)
#1=(1 2 3 . #1#)
con un po 'di CLOS aggiunto:
(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
Grazie, questo è molto utile. –
Ci sono libri o siti che suggerisci che potrebbero aiutarmi a saperne di più su questo tipo di cose? –
C'è una sezione in Let Over Lambda sulle espressioni cicliche: http://letoverlambda.com/index.cl/guest/chap4.html#sec_5 –
Ecco un'idea elaborata per un elenco circolare 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")
Non sto dando funzioni di defun per aggiungere, rimuovere e accedere agli elementi. Sto pensando che ciò che ho dato è sufficiente per mostrare ciò che devi fare in tutte le funzioni che definisci per questo tipo di elenco circolare. Mi è sembrato di lavorare nell'ascoltatore.
- 1. Stream in Common Lisp?
- 2. (comporre) in Common Lisp
- 3. Come stampare un elenco come matrice in Common Lisp
- 4. Ridenominazione lambda in Common Lisp
- 5. Moltiplicazione matrice in Common Lisp
- 6. Sviluppo Web in Common Lisp
- 7. Common Lisp definizione pacchetto
- 8. Common lisp gray stream
- 9. Esercizi Common Lisp/problemi
- 10. Association nel Common Lisp
- 11. Trasposizione di elenchi in Common Lisp
- 12. srotolare/argomenti splat in Common Lisp
- 13. sezioni in stile Haskell in Common Lisp
- 14. Common Lisp: cosa significa # + nil?
- 15. Problemi con ltk (common lisp)
- 16. Clojure lasciare vs Common Lisp lasciare
- 17. Disegno di alberi in Common Lisp
- 18. La migliore struttura web in Common-lisp?
- 19. loop su caratteri in stringa, Common Lisp
- 20. Uso di etichette in Common Lisp
- 21. Scraping una tabella HTML in Common Lisp?
- 22. Come funziona append in Common Lisp?
- 23. Representational State Transfer (REST) in Common Lisp
- 24. Introspezione di classe in Common Lisp
- 25. Stato di reset in Common Lisp
- 26. Mandelbrot Imposta implementazione in Common Lisp
- 27. In Common Lisp cos'è una rappresentazione stampata?
- 28. Scrittura di una macro ++ in Common Lisp
- 29. Divisione di interi in Common Lisp?
- 30. Memorizzazione delle date in Common Lisp
Vedere anche [Liste cicliche Lisp] (http://stackoverflow.com/q/15536564/1281433) e [Esempio di macro del lettore di segno uguale Sharpsign] (http://stackoverflow.com/q/12649290/1281433). –