Стиль Лисп: setq против setf

Питер Норвиг упоминает в парадигмах программирования искусственного интеллекта на стр. 50, компромисс между специфичностью и согласованностью и выбором использования setq или setf для обновления переменной до ценность. Что вы порекомендуете? Вы когда-нибудь сталкивались с ситуацией, когда это имело гораздо большее значение, чем удобочитаемость?


person Brendan Foote    schedule 09.06.2009    source источник


Ответы (6)


Использование setq более низкоуровневое, но производительность setf не является проблемой. А setf позволяет вам (или разработчикам библиотеки) предоставлять настраиваемое поведение setf, например, устанавливать части настраиваемых структур данных. Я говорю: используйте setf везде, если у вас нет причин не делать этого.

Также см. «Практический Common Lisp», глава 3: «Макрос SETF является основным оператором присваивания Common Lisp». PCL доступен в Интернете бесплатно: http://gigamonkeys.com/book/

person Harold L    schedule 09.06.2009

FWIW, я всегда использую setf. Если я немного изменю структуру своего кода, мне просто нужно будет изменить «место» вместо места и оператора (setq -> setf).

Кроме того, не беспокойтесь о производительности, setf точно такой же, как setq для символов:

CL-USER> (macroexpand '(setf foo 42))
(SETQ FOO 42)
person jrockway    schedule 12.06.2009

Вы можете использовать setf везде, где могли бы использовать setq. Фактически, setf - это макрос, основанный на setq. Итак, это должно быть чисто проблемой удобочитаемости и стиля.

Почти весь код, который я видел, избегает использования setq и использует setf.

person Ville Laurikari    schedule 09.06.2009

setf - это «поле набора», он меняет место и может иметь расширения пользователя. setq устанавливается с указанием первого аргумента в кавычки.

person Anton Kazennikov    schedule 11.06.2009

Я рекомендую вам последовать последнему совету Норвига в этом разделе: будьте последовательны. «Читаемость», конечно, самая важная причина сделать любой выбор в программировании. Если важно сообщить читателю (возможно, через 2 месяца), что вы имеете дело со всей ячейкой значения символа, тогда используйте setq; в противном случае используйте setf. Но только если вы будете последовательны.

person user78171    schedule 11.06.2009

Вы не ошибетесь, если везде будете использовать setf вместо setq.

Именно такие вещи уводят Common Lisp от дальнейшего развития, множество неиспользуемых вещей, которые разработчикам по-прежнему необходимо поддерживать.

person Marko    schedule 12.06.2009
comment
Я возражаю против второго предложения. SETF - это удобная абстракция нескольких конструкций присваивания, одна из которых - SETQ. Вы не можете реализовать SETF без SETQ. - person Svante; 12.06.2009
comment
2Сванте: но сложно представить ситуации, когда вам нужно было бы использовать setq вместо setf. - person Anton Kazennikov; 14.06.2009
comment
Дело не в этом - TAGBODY и GO тоже никто не использует в коде высокого уровня, но от них зависят реализации многих распространенных конструкций. - person Svante; 14.06.2009