2013-12-03 2 views
3

Я тестирую код в this interesting answer.Является ли это конкретным поведением для конкретных букв?

CL-USER> (defun literal-cons() 
     (let ((cons '(1 . 2))) 
      (incf (cdr cons)) 
      cons)) 
; in: DEFUN LITERAL-CONS 
;  (INCF (CDR CONS)) 
; --> LET* 
; ==> 
; (SB-KERNEL:%RPLACD #:CONS1 #:NEW0) 
; 
; caught WARNING: 
; Destructive function SB-KERNEL:%RPLACD called on constant data. 
; See also: 
;  The ANSI Standard, Special Operator QUOTE 
;  The ANSI Standard, Section 3.2.2.3 
; 
; compilation unit finished 
; caught 1 WARNING condition 
LITERAL-CONS 
CL-USER> (literal-cons) 
(1 . 3) 
CL-USER> (literal-cons) 
(1 . 3) 
CL-USER> (literal-cons) 
(1 . 3) 

Поскольку поведение не то же самое, мне интересно, если SBCL использовал упомянутое предупреждение, чтобы изменить поведение в чем-то думает, что более вероятно, ожидать от пользователя? Ожидается:

TEST> (defun literal-cons() 
     (let ((cons '(1 . 2))) 
      (incf (cdr cons)) 
      cons)) 
LITERAL-CONS 
TEST> (literal-cons) 
(1 . 3) 
TEST> (literal-cons) 
(1 . 4) 
TEST> (literal-cons) 
(1 . 5) 

ответ

4

Короткий ответ: да, это специфическое поведение для реализации. Как обсуждалось в Unexpected persistence of data,

Соответствующий текст из HyperSpec на quote является:

Последствия не определены, если буквальные объекты (в том числе цитируемым объекты) деструктивно изменены.

Это означает, что любого поведения вы видите из такой функции конкретной реализации (даже если некоторые модели поведение является более распространенным среди реализаций, чем другие).

0

Вы должны использовать:

(let ((cons (cons 1 2))) 
    (defun nonliteral-cons() 
     (incf (cdr cons)) 
     cons))