Я работаю с использованием среды визуального программирования для музыкальной композиции на основе CL. Я пытаюсь создать функцию, которая, если дано сказать, 3 элемента (1 2 3) вернет 1, 2, 3, 1, 2, 3 и т. Д., По одному числу в каждый раз при каждой оценке. В книге Common Lisp a Gentle Introduction кратко упоминается, что можно создавать круговые списки с использованием четкой нотации, но не вдаваться в подробности о том, как их использовать. Имейте в виду, что я могу вставить фактический код Lisp в программу, используя специально разработанный для этого объект.Циркуляр в Common Lisp
ответ
В Sharpsign Equal-Sign обозначение, это как #0=(1 2 3 . #0#)
.
Вот функция, которая создает такой список из приведенных аргументов:
(defun circular (first &rest rest)
(let ((items (cons first rest)))
(setf (cdr (last items)) items)))
Затем, вызывая (circular 1 2 3)
вернет циклический список, что вы хотели. Просто используйте car
и cdr
для повторения элементов до бесконечности.
И если вы действительно хотите функцию итератора, который не принимает никаких аргументов и возвращает следующий элемент для каждого вызова, вот как вы можете это сделать:
(defun make-iter (list)
(lambda()
(pop list)))
Вы можете использовать PROG1 вместо LET. –
@ThomasBartscher Спасибо! Теперь это реализовано. (На самом деле я посмотрел на ответ Райнера, и кажется, что «поп» делает то же самое, что и я. Вот что происходит, когда Schemer пытается написать CL.;)) –
Хм, я об этом не думал. Ницца! –
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#)
Пример:
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
также:
CL-USER 6 > '#1=(1 2 3 . #1#)
#1=(1 2 3 . #1#)
W с бит 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
Спасибо вам, это очень полезно. –
Есть ли какие-нибудь книги или сайты, которые вы предлагаете, которые помогут мне узнать больше об этом? –
Есть раздел в Let Over Lambda по циклическим выражениям: http://letoverlambda.com/index.cl/guest/chap4.html#sec_5 –
Вот идея, разработанная для кругового списка в Лиспе.
;;; 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")
Я не предоставляю функции defun для добавления, удаления и доступа к элементам. Я думаю, что то, что я дал, достаточно, чтобы показать, что вам нужно делать в любых функциях, которые вы определяете для такого кругового списка. Мне показалось, что я работаю в Слушателе.
- 1. Ассоциация в Common Lisp
- 2. Потоки в Common Lisp?
- 3. Замены в Common Lisp
- 4. Common Lisp Параллельное программирование
- 5. Common Lisp SublimeREPL
- 6. Common Lisp Unbound Variable
- 7. Цитата из Common Lisp
- 8. Matrix Transpose Common Lisp
- 9. Webdevelopment in Common Lisp
- 10. Common Lisp Weak References?
- 11. Weird синтаксис Common Lisp
- 12. Common Lisp Timer
- 13. Common lisp gray streams
- 14. Common Lisp рекурсивных макроподстановок
- 15. common lisp и emacs
- 16. Common Lisp Упражнения/Проблемы
- 17. Common Lisp: создание каталога
- 18. Реализация Common Lisp `format`
- 19. Сортировка полиномов Common Lisp
- 20. Scheme vs Common Lisp
- 21. + Vector Common Lisp
- 22. Common Lisp Эквивалент `man`
- 23. Сравнение символов в Common Lisp
- 24. Несвязанная переменная в Common Lisp
- 25. Переименование лямбды в Common Lisp
- 26. Взаимная рекурсия в Common Lisp
- 27. Написание макроса ++ в Common Lisp
- 28. Интроспекция класса в Common Lisp
- 29. Целое подразделение в Common Lisp?
- 30. Транспонирование списков в Common Lisp
Также см. [Циклические списки Lisp] (http://stackoverflow.com/q/15536564/1281433) и [Пример макроса считывателя с открытым символом Sharpign] (http://stackoverflow.com/q/12649290/1281433). –