Питер Норвиг упоминает в Paradigms of Artificial Intelligence Programming, о page 50, компромисс между спецификой и согласованностью и при выборе использования setq или setf для обновления переменной до значения. Что вы порекомендуете? Вы когда-нибудь сталкивались с ситуацией, когда это имело большое значение для читаемости?Стиль Lisp: setq vs. setf
ответ
Использование setq более низкоуровневое, но производительность setf не является проблемой. И setf позволяет вам (или библиотечным писателям) предоставлять настраиваемое поведение setf, например, настраивать части пользовательских структур данных. Я говорю: пойдите с setf везде, если у вас нет причин не делать этого.
См. Также Практический общий Лисп, глава 3: «Макрос SETF является основным оператором присваивания Common Lisp». PCL можно скачать бесплатно: http://gigamonkeys.com/book/
Вы можете использовать setf
везде, где вы могли бы использовать setq
. Фактически, setf
- фактически макрос, который строится на setq
. Таким образом, это должно быть чисто читаемостью и стилем.
Почти весь код, который я видел, избегает использования setq
и использует setf
.
Я рекомендую вам следовать окончательному совету Норвига в этом разделе: быть последовательным. «Читаемость» - это, конечно, самая важная причина для выбора в программировании. Если важно сообщить читателю (возможно, вам через 2 месяца), что вы имеете дело со всей ячейкой значений символа, используйте setq
; в противном случае используйте setf
. Но только если вы согласны.
setf является «полем установки», оно меняет место и может иметь пользовательские расширения. setq устанавливается с цитированием первого аргумента.
FWIW, я всегда использую setf
. Если я немного изменил структуру своего кода, мне просто нужно изменить «место» вместо места и оператора (setq -> setf).
Кроме того, не беспокоиться о производительности, SETF точно так же, как и для SETQ символов:
CL-USER> (macroexpand '(setf foo 42))
(SETQ FOO 42)
Вы не ошибетесь, если вы использовали SETF везде вместо SETQ.
Это то, что тянет Common Lisp от продвижения вперед, много неиспользуемого материала, который разработчикам по-прежнему необходимо поддерживать.
- 1. LISP - Ближайшая функция без SETQ/SETF и т.д.
- 2. Разница между `set`,` setq` и `setf` в Common Lisp?
- 3. перезаписать без использования set, setf или setq
- 4. setq vs Undeclared free variable (common lisp)
- 5. Lisp scope выпуск с setq?
- 6. setq и defvar в Lisp
- 7. Разница между setq и setq-default в Emacs Lisp
- 8. Общий lisp: удалите пару в alist через setq и свяжите
- 9. В чем разница между defvar, defparameter, setf и setq
- 10. Несвязанная переменная в Lisp
- 11. SETF в Clojure
- 12. Я не могу использовать setq в sbcl [LISP]
- 13. Перегруппировать элементы списка в lisp
- 14. common lisp programming EQ error
- 15. Динамический массив 2d в lisp
- 16. Scheme vs Common Lisp
- 17. (list ...) vs '(...) в Lisp
- 18. LET и SETF в commonLISP
- 19. Оценка форм setf
- 20. Реализация Мандельброта в Common Lisp
- 21. переменная unbound в lisp при использовании threading в sbcl lisp
- 22. Неопределенная ошибка функции в LISP
- 23. Ошибка синтаксиса в общем цикле Lisp Loop
- 24. Динамические переменные в Emacs Lisp
- 25. Lisp - Сделать список с переменным значением
- 26. Почему Setq работает, но не позволяет?
- 27. Lisp vs Python - статическая компиляция
- 28. Что изучать Scheme vs Lisp
- 29. Настройка равной функции в общем lisp с использованием только «eq»
- 30. определения пользовательской SEtF для класса в сюсюкать
Я возражаю против второго предложения. SETF - это удобная абстракция над несколькими конструкциями присваивания, одним из которых является SETQ. Вы не можете реализовать SETF без SETQ. – Svante
2Svante: но трудно представить ситуации, в которых вам нужно будет использовать setq вместо setf. –
Это не главное - никто не использует TAGBODY и GO в коде высокого уровня, но реализация многих общих конструкций зависит от них. – Svante