?

Log in

парочка вопросов - Жить не можем без проблем! [entries|archive|friends|userinfo]
Жить не можем без проблем!

[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

парочка вопросов [Apr. 7th, 2012|12:39 pm]
Жить не можем без проблем!
ru_lisp
[l10n_be]
В процессе изучения Лиспа натыкаюсь на некоторые моменты, с которыми пока не могу разобраться.

1) sbcl & nunion

Введём такой простой код в repl clisp, gcl и sbcl
(setf a '(1 2 3))
(setf b '(4 5 6))
(nunion a b)
; clisp, gcl => '(1 2 3 4 5 6)
; sbcl => '(3 2 1 4 5 6)

А теперь узнаем значение a: в clisp и gcl получим '(1 2 3 4 5 6), а в sbcl -- '(1 4 5 6).

Вопрос: кто неправ? У clisp и gcl результат логичный и ожидаемый, у sbcl -- не пойми что. Если поведение sbcl правильное, то каков смысл в существовании nunion?

HyperSpec ситуацию не прояснил.

2) gcl

Возьмём такую простую программку для проверки:

(defun test (a)
(print a))

(test 6)

$ gcl -f test.lisp

Error: The variable A is unbound.
Fast links are on: do (si::use-fast-links nil) for debugging
Error signalled by SYSTEM::SET-UP-TOP-LEVEL.
Backtrace: PRINT

Если в начало добавить (si::use-fast-links nil), то запускается. Чего он хочет?
linkReply

Comments:
From: (Anonymous)
2012-04-07 01:12 pm (UTC)
Деструктивные функции могут делать с передаваемыми списками что угодно, так что вызывая их, вы говорите: «Мне нужно эффективно сделать операцию, а то, что я передаю в аргументах, мне больше не нужно, делай, с ним что хочешь, только побыстрее». Подчеркну, что это функции, а не процедуры, поэтому вызывать их надо ради возвращемого результата, а не того, что они делают с аргументами. Хотите более переносимого эффекта — используйте union вместо nunion.

Что касается gcl, то разве он не мёртв?
(Reply) (Thread)
[User Picture]From: lispnik
2012-04-07 01:13 pm (UTC)
Это был я, почему-то отправилось от анонима.
(Reply) (Parent) (Thread)
[User Picture]From: smilga
2012-04-07 01:55 pm (UTC)
Что касается gcl, то разве он не мёртв?

Сложно сказать. Траффик на почтовой рассылке там поживее, чем у многих живых проектов.
(Reply) (Parent) (Thread)
From: l10n_be
2012-04-07 02:15 pm (UTC)
вызывать их надо ради возвращемого результата, а не того, что они делают с аргументами

Понятно...

Что касается gcl, то разве он не мёртв?

До сих пор есть в Debian, но версия ещё 2005 года, но и CL не нов :)
(Reply) (Parent) (Thread)
[User Picture]From: love5an
2012-04-07 01:48 pm (UTC)
GCL мёртв, тухл, и глючен.

SBCL - каноническая, можно сказать, реализация CL. Поведение SBCL обычно наиболее соответствует стандарту.

nunion - деструктивная функция, как сказали. Смысл деструктивных функций в том, что они с аргументами могут делать что угодно, т.е. последние становятся как бы невалидными, после использования. Смысл существования деструктивных функций в экономии памяти и процессорного времени(например nreverse просто переназначает ссылки в cons-ячейках, и работает за линейное время и без расхода дополнительной памяти, в отличие от просто reverse). Но, да, это по-прежнему функции, т.е. их используют ради возвращаемого значения.

Еще такой момент - в деструктивные функции нежелательно передавать объекты-литералы, особенно встроенных типов(cons-ячейки те же). Константы, записанные в разных местах компилятор может сворачивать в одну. А это чревато нежелательными побочными эффектами, как понятно.
(Reply) (Thread)
[User Picture]From: love5an
2012-04-07 01:49 pm (UTC)
Ну, про объекты литералы еще - из вышесказанного понятно, естественно, что их нежелательно менять каким-либо образом(в случае с cons - соответственно нежелательно использовать (setf car), (setf cdr) и т.п.).
(Reply) (Parent) (Thread)
From: l10n_be
2012-04-07 02:22 pm (UTC)
А (setf (nth n *list*) (do-something-with (nth n *list*)) можно?
(Reply) (Parent) (Thread)
[User Picture]From: love5an
2012-04-07 03:28 pm (UTC)
зависит от того что такое *list*
короче, если объекты - константы/литераты(из кода или из load-time-value например) - их модифицировать нельзя.
(Reply) (Parent) (Thread)