Питер Норвиг упоминает в парадигмах программирования искусственного интеллекта на стр. 50, компромисс между специфичностью и согласованностью и выбором использования setq или setf для обновления переменной до ценность. Что вы порекомендуете? Вы когда-нибудь сталкивались с ситуацией, когда это имело гораздо большее значение, чем удобочитаемость?
Стиль Лисп: setq против setf
Ответы (6)
Использование setq более низкоуровневое, но производительность setf не является проблемой. А setf позволяет вам (или разработчикам библиотеки) предоставлять настраиваемое поведение setf, например, устанавливать части настраиваемых структур данных. Я говорю: используйте setf везде, если у вас нет причин не делать этого.
Также см. «Практический Common Lisp», глава 3: «Макрос SETF является основным оператором присваивания Common Lisp». PCL доступен в Интернете бесплатно: http://gigamonkeys.com/book/
FWIW, я всегда использую setf
. Если я немного изменю структуру своего кода, мне просто нужно будет изменить «место» вместо места и оператора (setq -> setf).
Кроме того, не беспокойтесь о производительности, setf точно такой же, как setq для символов:
CL-USER> (macroexpand '(setf foo 42))
(SETQ FOO 42)
Вы можете использовать setf
везде, где могли бы использовать setq
. Фактически, setf
- это макрос, основанный на setq
. Итак, это должно быть чисто проблемой удобочитаемости и стиля.
Почти весь код, который я видел, избегает использования setq
и использует setf
.
setf - это «поле набора», он меняет место и может иметь расширения пользователя. setq устанавливается с указанием первого аргумента в кавычки.
Я рекомендую вам последовать последнему совету Норвига в этом разделе: будьте последовательны. «Читаемость», конечно, самая важная причина сделать любой выбор в программировании. Если важно сообщить читателю (возможно, через 2 месяца), что вы имеете дело со всей ячейкой значения символа, тогда используйте setq
; в противном случае используйте setf
. Но только если вы будете последовательны.
Вы не ошибетесь, если везде будете использовать setf вместо setq.
Именно такие вещи уводят Common Lisp от дальнейшего развития, множество неиспользуемых вещей, которые разработчикам по-прежнему необходимо поддерживать.