Библиотека knigago >> Литература по изданиям >> Самиздат, сетевая литература >> Nikodemus' Common Lisp FAQ


"15 суток, или Можете жаловаться!" Андрея Кивинова – это искрометный ироничный детектив, который заставит вас смеяться и волноваться в равной мере. Главным героем книги является капитан Фролов, которого ошибочно арестовывают и отправляют под стражу на 15 суток. Однако, находясь за решеткой, он становится свидетелем убийства и решает провести собственное расследование. Автор погружает читателей в мир криминала, коррупции и бюрократических неурядиц. Кивинов мастерски создает ярких и...

Nikodemus Siivola - Nikodemus' Common Lisp FAQ

Nikodemus' Common Lisp FAQ
Книга - Nikodemus
Название:
Nikodemus' Common Lisp FAQ
Nikodemus Siivola

Жанр:

Самиздат, сетевая литература, Литература ХXI века (эпоха Глобализации экономики), Любительские переводы, Lisp, Scheme

Изадано в серии:

неизвестно

Издательство:

Интернет-издательство «Stribog»

Год издания:

ISBN:

неизвестно

Отзывы:

Комментировать

Рейтинг:

Поделись книгой с друзьями!

Помощь сайту: донат на оплату сервера

Краткое содержание книги "Nikodemus' Common Lisp FAQ"

Последнее обновление: 2012-04-13.

Это очень неофициальное ЧаВО по языку Common Lisp, отражающее субъективное мнение Nikodemus Siivola. Этот текст частично основан на других ЧаВО, встречавшихся на просторах интернета и comp.lang.lisp.

Если вы думаете, что я воспользовался вашим текстом, буду рад признаться в этом, поэтому пишите на nikodemus@random-state.net.

Текущая версия этого ЧаВО доступна по следующим адресам:

http://random-state.net/files/nikodemus-cl-faq.txt

http://random-state.net/files/nikodemus-cl-faq.html

ЧаВО также периодически публикуется в comp.lang.lisp.

Читаем онлайн "Nikodemus' Common Lisp FAQ". [Страница - 4]

     (mapcar (lambda (elt)

                 (apply function elt args))

              list))

Незачем писать MAP-LIST-WITH-1 с помощью APPLY, вызов FUNCALL почти наверняка будет более эффективным.

В противовес MAP-LIST-WITH-N не может быть написан с использованием FUNCALL, поскольку количество аргументов вызывающей стороне неизвестно. Следует использовать APPLY.

SET, SETQ и SETF — в чем разница, что использовать?

Короткий ответ: всегда используйте SETF.


Развернутый ответ: Давным давно, когда еще не было Common Lisp, не было лексических переменных, были только динамические. И не было тогда ни SETQ, ни SETF, только SET. То, что сегодня пишется как

(setf (symbol-value '*foo*) 42)

записывалось так

(set (quote *foo*) 42)

что со временем сократилось до SETQ (SET Quoted)

(setq *foo* 42)

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

Позже кто-то изобрел SETF (SET Field) как обобщенный способ присвоения значений в структурах данных, зеркальное отображение L-значений в других языках:

x.car:= 42;

записывается как

(setf (car x) 42)

Для симметрии и общности, SETF также включает в себя функциональность SETQ. Можно сказать, что SETQ был низкоуровневым примитивом, а SETF — высокоуровневой операцией.

Потом появились символьные макросы. Поскольку символьные макросы прозрачны, было сделано так, что SETQ ведет себя как SETF в случае, когда присваиваемая «переменная» на деле символьный макрос:

(defvar *hidden* (cons 42 42))

(define-symbol-macro foo (car *hidden*))


foo => 42


(setq foo 13)


foo => 13


*hidden* => (13. 42)

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

Всегда пользуйтесь SETF.

'(1 2 3) или (list 1 2 3)?

Короткий ответ: пишите

(list 1 2 3)

пока не поймете разницу. Если вы пишете

'(1 2 3)

не модифицируйте это деструктивно (т. е. с помощью SORT или NREVERSE).


Развернутый ответ: Во-первых, одинарная кавычка — это макрос, преобразующий

'anything

в

(quote anything)

во время чтения, так что

'(1 2 3) === (quote (1 2 3))

Во-вторых, QUOTE — это специальный оператор, возвращающий свои аргументы невычисленными. Так

'(1 2 3)

возвращает буквальный (literal) список. Как и в большинстве языков модификация буквальных (literal) данных приводит к неопределенным последствиям. Например, компилятор может соединить константы, содержащие литералы:


(let ((a '(1 2 3))

(b '(1 2 3)))

(eq a b)) ; => T или NIL

Следствием является тот факт, что изменяя A, также может измениться и B. Тогда для чего годится QUOTE?

Если, например, у вас есть большие неизменяемые списки, которые компилятор может соединить, то пометка их как буквальные (literal) дает компилятору право так поступить.

Что за *УШКИ*?

Что бы вы ни использовали для объявления переменных, DEFVAR или DEFPARAMETER, всегда делайте *ТАКОЕ-ИМЯ*. И не делайте так для локальных переменных.

(defvar *очень-хорошо*…)

(defvar это-очень-плохо…)

Зачем? Если вы еще не знаете, что такое специальные переменные, продолжайте читать ту книжку, которую читаете и возвращайтесь как закончите, а пока используйте ушки.

Ушки защищают от двух простых ошибок, которые очень легко сделать.

Ошибка 1: случайное связывание специальной переменной

(defparameter foo "foo!")


(defun say-it ()

     (write-line foo))


(defun say-more (foo)

     (say-it)

     (format t "now say ~A~%" foo))


Теперь

(say-more "bar!")

напечатает

say bar!

now say bar!

вместо ожидаемого

say foo!

now say bar!

… упс!

Ошибка 2: из-за опечатки производится чтение из специальной вместо локальной переменной, предупреждения не выдается

Обычно вы получите предупреждение времени компиляции и ошибку времени выполнения в случае

(defun foo (bar)

     bat)

но если перед этим написать

(defparameter bat "baseball")

то ошибки не будет и вы потратите уйму времени на отладку, пытаясь понять, что не так.

Если пишете код для себя, все равно, ставите вы ушки или нет, но когда вы публикуете код, отсутствие *ушек* означает трату времени других людей. Не делайте так, пожалуйста!

Отсутствие ушек создает ощущение ошибки: когда я вижу

(defparameter нет-ушек…)

я понимаю, что нужно читать код особенно осторожно, потому как нет никакой гарантии, что код, который с первого --">

Оставить комментарий:


Ваш e-mail является приватным и не будет опубликован в комментарии.