2009-06-09 2 views
21

Питер Норвиг упоминает в Paradigms of Artificial Intelligence Programming, о page 50, компромисс между спецификой и согласованностью и при выборе использования setq или setf для обновления переменной до значения. Что вы порекомендуете? Вы когда-нибудь сталкивались с ситуацией, когда это имело большое значение для читаемости?Стиль Lisp: setq vs. setf

ответ

15

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

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

9

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

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

1

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

3

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

10

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

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

CL-USER> (macroexpand '(setf foo 42)) 
(SETQ FOO 42) 
-2

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

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

+3

Я возражаю против второго предложения. SETF - это удобная абстракция над несколькими конструкциями присваивания, одним из которых является SETQ. Вы не можете реализовать SETF без SETQ. – Svante

+0

2Svante: но трудно представить ситуации, в которых вам нужно будет использовать setq вместо setf. –

+5

Это не главное - никто не использует TAGBODY и GO в коде высокого уровня, но реализация многих общих конструкций зависит от них. – Svante

Смежные вопросы