1

我是 Lisp 的新手,所以当我在 SBCL 中编写函数时

(defun subst (new old l)
  (cond   
   ((null l) '())
   ((eq old (car l)) (cons new (cdr l)))
   ((cons (car l) (subst new old (cdr l))))))

它给出了错误 SYMBOL-PACKAGE-LOCKED-ERROR,一个样式警告和一个警告,请帮助解决它

4

1 回答 1

4

您正在尝试重新定义cl:subst. 根据HyperSpec 的§11.1.2.1.2,当你尝试这样做时会发生什么是未定义的。大多数实现都有某种包锁来防止这种重新定义。您可以通过解锁包来解决这些问题,但在这种情况下,最好使用除subst(例如,my-subst)以外的名称,或者定义一个新包,例如my-cl,阴影cl:subst和定义my-cl:subst

SBCL 给出的错误实际上提供了相当多的信息,并提供了对我在上面链接到的 HyperSpec 页面以及SBCL 手册中的第 11 章包锁的参考:

* (defun subst (new old l) 
    (cond
      ((null l) '())
      ((eq old (car l)) (cons new (cdr l)))
      ((cons (car l) (subst new old (cdr l))))))
; in: DEFUN SUBST
;     (SB-INT:NAMED-LAMBDA SUBST
;         (NEW OLD L)
;       (BLOCK SUBST (COND ((NULL L) 'NIL) ((EQ OLD #) (CONS NEW #)) ((CONS # #)))))
; ==>
;   #'(SB-INT:NAMED-LAMBDA SUBST
;         (NEW OLD L)
;       (BLOCK SUBST
;         (COND ((NULL L) 'NIL) ((EQ OLD #) (CONS NEW #)) ((CONS # #)))))
; 
; caught STYLE-WARNING:
;   The definition has no &KEY arguments, but the proclamation did.

;     (SUBST NEW OLD (CDR L))
; 
; caught WARNING:
;   recursion in known function definition
;     policy=((COMPILATION-SPEED . 1) (DEBUG . 1) (INHIBIT-WARNINGS . 1)
;             (SAFETY . 1) (SPACE . 1) (SPEED . 1))
;     arg types=(T T T)
; 
; compilation unit finished
;   caught 1 WARNING condition
;   caught 1 STYLE-WARNING condition
STYLE-WARNING: redefining COMMON-LISP:SUBST in DEFUN

debugger invoked on a SYMBOL-PACKAGE-LOCKED-ERROR in thread #<THREAD
                                                              "initial thread" RUNNING
                                                               {1002978E71}>:
  Lock on package COMMON-LISP violated when setting fdefinition of SUBST while
  in package COMMON-LISP-USER.
See also:
  The SBCL Manual, Node "Package Locks"
  The ANSI Standard, Section 11.1.2.1.2
于 2013-04-30T14:17:21.483 回答