Вопрос по – Изменение списка, переданного в качестве параметра, дает разные результаты в SBCL и CLISP

1

Может кто-нибудь объяснить, почему я получаю разные результаты для следующей простой программы с sbcl и clisp? То, что я делаю, не определено языком, или один из двух интерпретаторов lisp не прав?

; Modify the car of the passed-in list
(defun modify (a) (setf (car a) 123))

; Create a list and print car before and after calling modify
(defun testit () (let ((a '(0)))
                   (print (car a))
                   (modify a)
                   (print (car a))))
(testit)

SBCL (версия 1.0.51) производит:

0 
0 

CLISP (версия 2.49) выдает (что я и ожидал):

0 
123 
посмотреть здесь:stackoverflow.com/questions/8962909/… Vsevolod Dyomkin
Возможно, это связано с тем, что вы модифицируете буквальный список. Попробуйте изменить это наlet ((a (cons 0 nil))) Seth Carnegie

Ваш Ответ

1   ответ
2

что это связано с вашей модификацией буквальных данных. Попробуйте использовать(list 0) вместо'(0), Вопросы, относящиеся к этому, возникают относительно часто, поэтому я процитируюHyperSpec Вот.

3.7.1 Модификация литеральных объектов:

The consequences are undefined if literal objects are destructively modified.

определение «буквальный»:

literal adj. (of an object) referenced directly in a program rather than being computed by the program; that is, appearing as data in a quote form, or, if the object is a self-evaluating object, appearing as unquoted data. ``In the form (cons "one" '("two")), the expressions "one", ("two"), and "two" are literal objects.''

Обратите внимание, что часто (во многих реализациях), если вы изменяете литеральные значения, вы действительно изменяете их в самом коде & # x2013; пишуself modifying code, Ваш пример кода не будет работать так, как вы ожидаете.

Ваш пример кода в CCL:

CL-USER> (defun modify (a) (setf (car a) 123))
MODIFY
CL-USER> (defun testit ()
           (let ((a '(0)))
             (print (car a))
             (modify a)
             (print (car a))))
TESTIT
CL-USER> (testit)

0 
123 
123
CL-USER> (testit)

123 
123 
123

Взгляните на вторую оценкуtestit, гдеlet само по себе уже содержит измененное значение, таким образом, первоеprint также дает123.

Также см:Lisp, минусы и (число. Число) разницагде я объяснил это более подробно, или вопрос, связанный с комментарием Всеволода выше.

Error: User Rate Limit Exceeded Gregg
Error: User Rate Limit Exceeded

Похожие вопросы