我从书中删除了一个例子:ANSI Common Lisp,第14.6章条件。
但是check-type和assert示例在sbcl中不起作用。 我怎样才能输入新值?无论我输入什么新值,它总是失败。
但是,它适用于clisp。
示例代码:
(let ((x '(a b c))) (check-type (car x) integer "an integer") x)
(let ((sandwich '(ham on rye)))
(assert (eql (car sandwich) 'chicken)
((car sandwich))
"I wanted a ~a sandwich." 'chicken)
sandwich)
在sbcl中: 示例1:
* (let ((x '(a b c))) (check-type (car x) integer "an integer") x)
; in: LET ((X '(A B C)))
; (CHECK-TYPE (CAR X) INTEGER "an integer")
; --> DO BLOCK LET TAGBODY TAGBODY SETF
; ==>
; (SB-KERNEL:%RPLACA X
; (SB-KERNEL:CHECK-TYPE-ERROR '(CAR X) #:G0 'INTEGER
; "an integer"))
;
; caught WARNING:
; Destructive function SB-KERNEL:%RPLACA 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
debugger invoked on a SIMPLE-TYPE-ERROR in thread
#<THREAD "main thread" RUNNING {B3E2341}>:
The value of (CAR X) is A, which is not an integer.
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [STORE-VALUE] Supply a new value for (CAR X).
1: [ABORT ] Exit debugger, returning to top level.
(SB-KERNEL:CHECK-TYPE-ERROR (CAR X) A INTEGER "an integer")
0] 0
Type a form to be evaluated: 0
debugger invoked on a SIMPLE-TYPE-ERROR in thread
#<THREAD "main thread" RUNNING {B3E2341}>:
The value of (CAR X) is A, which is not an integer.
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [STORE-VALUE] Supply a new value for (CAR X).
1: [ABORT ] Exit debugger, returning to top level.
(SB-KERNEL:CHECK-TYPE-ERROR (CAR X) A INTEGER "an integer")
0]
例2:
* (let ((sandwich '(ham on rye)))
(assert (eql (car sandwich) 'chicken)
((car sandwich))
"I wanted a ~a sandwich." 'chicken)
sandwich)
; in: LET ((SANDWICH '(HAM ON RYE)))
; (ASSERT (EQL (CAR SANDWICH) 'CHICKEN) ((CAR SANDWICH))
; "I wanted a ~a sandwich." 'CHICKEN)
; --> TAGBODY SETF
; ==>
; (SB-KERNEL:%RPLACA SANDWICH
; (SB-IMPL::ASSERT-PROMPT '(CAR SANDWICH) (CAR SANDWICH)))
;
; caught WARNING:
; Destructive function SB-KERNEL:%RPLACA 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
debugger invoked on a SIMPLE-ERROR in thread
#<THREAD "main thread" RUNNING {B3E2341}>:
I wanted a CHICKEN sandwich.
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [CONTINUE] Retry assertion with new value for (CAR SANDWICH).
1: [ABORT ] Exit debugger, returning to top level.
(SB-KERNEL:ASSERT-ERROR (EQL (CAR SANDWICH) (QUOTE CHICKEN)) (((CAR SANDWICH) HAM)) ((CAR SANDWICH)) "I wanted a ~a sandwich." CHICKEN)
0] 0
The old value of (CAR SANDWICH) is HAM.
Do you want to supply a new value? (y or n) y
Type a form to be evaluated:
'chicken
debugger invoked on a SIMPLE-ERROR in thread
#<THREAD "main thread" RUNNING {B3E2341}>:
I wanted a CHICKEN sandwich.
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [CONTINUE] Retry assertion with new value for (CAR SANDWICH).
1: [ABORT ] Exit debugger, returning to top level.
(SB-KERNEL:ASSERT-ERROR (EQL (CAR SANDWICH) (QUOTE CHICKEN)) (((CAR SANDWICH) HAM)) ((CAR SANDWICH)) "I wanted a ~a sandwich." CHICKEN)
0]
但是在clisp中,它运作良好。
[1]> (let ((x '(a b c))) (check-type (car x) integer "an integer") x)
*** - The value of (CAR X) should be an integer.
The value is: A
The following restarts are available:
STORE-VALUE :R1 Input a new value for (CAR X).
ABORT :R2 Abort main loop
Break 1 [2]> :R1
New (CAR X)> 99
(99 B C)
[3]> (let ((sandwich '(ham on rye)))
(assert (eql (car sandwich) 'chicken)
You are in the top-level Read-Eval-Print loop.
Help (abbreviated :h) = this list
Use the usual editing capabilities.
(quit) or (exit) leaves CLISP.
((car sandwich))
You are in the top-level Read-Eval-Print loop.
Help (abbreviated :h) = this list
Use the usual editing capabilities.
(quit) or (exit) leaves CLISP.
"I wanted a ~a sandwich." 'chicken)
sandwich)
** - Continuable Error
I wanted a CHICKEN sandwich.
If you continue (by typing 'continue'): Input a new value for (CAR SANDWICH).
The following restarts are also available:
ABORT :R1 Abort main loop
Break 1 [4]> continue
New (CAR SANDWICH)> 'chicken
(CHICKEN ON RYE)
[5]>
答案 0 :(得分:2)
您不应该修改文字数据。 Common Lisp标准中未定义后果。
这是未定义的:
(let ((x '(a b c)))
(setf (car x) 10))
这有效:
(let ((x (list 'a 'b 'c)))
(setf (car x) 10))