sbcl终端和sbcl文件

时间:2015-01-20 08:59:59

标签: common-lisp sbcl

(defun foo (&aux (defvar x 10))
   (print x))

定义一个局部变量X,就像LET一样。 相同的函数如果写在一个文件中,然后在sbcl上编译为:sbcl --script file.lisp 给出错误:

; in: DEFUN FOO
;     (DEFUN FOO (&AUX (DEFVAR X 10)) (PRINT X))
; --> PROGN SB-INT:NAMED-LAMBDA 
; ==>
;   #'(SB-INT:NAMED-LAMBDA FOO
;         (&AUX (DEFVAR X 10))
;       (BLOCK FOO (PRINT X)))
; 
; caught ERROR:
;   malformed &AUX binding specifier: (DEFVAR X 10)
; 
; compilation unit finished
;   caught 1 ERROR condition
unhandled SB-INT:COMPILED-PROGRAM-ERROR in thread #<SB-THREAD:THREAD
                                                    "main thread" RUNNING
                                                     {10029B8FC3}>:
  Execution of a form compiled with errors.
Form:
  #'(NAMED-LAMBDA FOO
      (&AUX (DEFVAR X 10))
    (BLOCK FOO (PRINT X)))
Compile-time error:
  malformed &AUX binding specifier: (DEFVAR X 10)

0: (SB-DEBUG::MAP-BACKTRACE
    #<CLOSURE (LAMBDA # :IN BACKTRACE) {1002A39DEB}>
    :START
    0
    :COUNT
    128)
1: (BACKTRACE 128 #<SB-SYS:FD-STREAM for "standard error" {10029BA863}>)
2: (SB-DEBUG::DEBUGGER-DISABLED-HOOK
    #<SB-INT:COMPILED-PROGRAM-ERROR {1002A373D3}>
    #<unavailable argument>)
3: (SB-DEBUG::RUN-HOOK
    *INVOKE-DEBUGGER-HOOK*
    #<SB-INT:COMPILED-PROGRAM-ERROR {1002A373D3}>)
4: (INVOKE-DEBUGGER #<SB-INT:COMPILED-PROGRAM-ERROR {1002A373D3}>)
5: (ERROR
    SB-INT:COMPILED-PROGRAM-ERROR
    :MESSAGE
    "malformed &AUX binding specifier: (DEFVAR X 10)"
    :SOURCE
    "#'(NAMED-LAMBDA FOO
      (&AUX (DEFVAR X 10))
    (BLOCK FOO (PRINT X)))")
6: (#:EVAL-THUNK)
7: (SB-INT:SIMPLE-EVAL-IN-LEXENV
    (SB-INT:NAMED-LAMBDA FOO
        (&AUX (DEFVAR X 10))
      (BLOCK FOO (PRINT X)))
    #<NULL-LEXENV>)
8: (SB-INT:SIMPLE-EVAL-IN-LEXENV
    (SB-IMPL::%DEFUN 'FOO
                     (SB-INT:NAMED-LAMBDA FOO
                         (&AUX (DEFVAR X 10))
                       (BLOCK FOO (PRINT X)))
                     NIL 'NIL (SB-C:SOURCE-LOCATION))
    #<NULL-LEXENV>)
9: (SB-INT:SIMPLE-EVAL-IN-LEXENV
    (EVAL-WHEN (:LOAD-TOPLEVEL :EXECUTE)
      (SB-IMPL::%DEFUN 'FOO
                       (SB-INT:NAMED-LAMBDA FOO
                           (&AUX (DEFVAR X 10))
                         (BLOCK FOO (PRINT X)))
                       NIL 'NIL (SB-C:SOURCE-LOCATION)))
    #<NULL-LEXENV>)
10: (SB-INT:SIMPLE-EVAL-IN-LEXENV
     (DEFUN FOO (&AUX (DEFVAR X 10)) (PRINT X))
     #<NULL-LEXENV>)
11: (EVAL-TLF (DEFUN FOO (&AUX (DEFVAR X 10)) (PRINT X)) 7 #<NULL-LEXENV>)
12: ((FLET SB-FASL::EVAL-FORM :IN SB-INT:LOAD-AS-SOURCE)
     (DEFUN FOO (&AUX (DEFVAR X 10)) (PRINT X))
     7)
13: (SB-INT:LOAD-AS-SOURCE
     #<SB-SYS:FD-STREAM for "file /home/student/3357/fib.lisp" {10029C1513}>
     :VERBOSE
     NIL
     :PRINT
     NIL
     :CONTEXT
     "loading")
14: ((FLET SB-FASL::LOAD-STREAM :IN LOAD)
     #<SB-SYS:FD-STREAM for "file /home/student/3357/fib.lisp" {10029C1513}>
     NIL)
15: (LOAD
     #<SB-SYS:FD-STREAM for "file /home/student/3357/fib.lisp" {10029C1513}>
     :VERBOSE
     NIL
     :PRINT
     NIL
     :IF-DOES-NOT-EXIST
     T
     :EXTERNAL-FORMAT
     :DEFAULT)
16: ((FLET SB-IMPL::LOAD-SCRIPT :IN SB-IMPL::PROCESS-SCRIPT)
     #<SB-SYS:FD-STREAM for "file /home/student/3357/fib.lisp" {10029C1513}>)
17: ((FLET #:WITHOUT-INTERRUPTS-BODY-5599 :IN SB-IMPL::PROCESS-SCRIPT))
18: (SB-IMPL::PROCESS-SCRIPT "fib.lisp")
19: (SB-IMPL::TOPLEVEL-INIT)
20: ((FLET #:WITHOUT-INTERRUPTS-BODY-236911 :IN SAVE-LISP-AND-DIE))
21: ((LABELS SB-IMPL::RESTART-LISP :IN SAVE-LISP-AND-DIE))

unhandled condition in --disable-debugger mode, quitting

分配变量&amp; aux?

的旧版本有什么问题

1 个答案:

答案 0 :(得分:4)

如果我们查看syntax of lambda lists,我们会看到:

lambda-list::= (var* 
                [&optional {var | (var [init-form [supplied-p-parameter]])}*] 
                [&rest var] 
                [&key {var | ({var | (keyword-name var)}
                             [init-form [supplied-p-parameter]])}*
                 [&allow-other-keys]] 
                [&aux {var | (var [init-form])}*]) 

上面是正常函数的参数列表声明的语法。

如果你查看你的表单,你可能想知道符号DEFVAR应该做什么,以及它是否在lambda列表中有意义......

让我们在REPL中试试吧

* (defun foo (&aux (defvar x 10))
   (print x))
; in: DEFUN FOO
;     (SB-INT:NAMED-LAMBDA FOO
;         (&AUX (DEFVAR X 10))
;       (BLOCK FOO (PRINT X)))
; 
; caught ERROR:
;   malformed &AUX binding specifier: (DEFVAR X 10)

debugger invoked on a SB-INT:SIMPLE-PROGRAM-ERROR:
  malformed &AUX binding specifier: (DEFVAR X 10)

SBCL清楚地检测到语法错误。