3

以下功能:

(defun check-for-arrow (x)
  (format t "**~s**~s**~s**~s**"
          (length (string x))
          x
          (eq x '->)
          (and (eq (elt (string x) 0) #\-)
               (eq (elt (string x) 1) #\>))) ; for debug
  (eq x '->))

从 REPL 调用时,使用:

(check-for-arrow '->)

打印,带跟踪:

0> Calling (CHECK-FOR-ARROW ->) 
**2**->**T**T**
<0 CHECK-FOR-ARROW returned T

相反,当在 Hunchentoot Web 应用程序中调用时,在表单中读取的数据上,当通过符号 '->' 调用时,会打印:

0> Calling (NORMALIZER::CHECK-FOR-ARROW ->) 
**2**->**NIL**T**
<0 NORMALIZER::CHECK-FOR-ARROW returned NIL

Lisp 是 Clozure Common Lisp。

这是否取决于不同的符号实习方式?可以在符号上使用“eq”,或者我必须转换字符串中的箭头并检查字符串是否相等?

谢谢。

4

1 回答 1

6

Common Lisp 有包。包是符号的命名空间。

因此,可以有许多不同的符号,命名为“->”,每个符号都在不同的包中。

因此normalizer::->不一定EQcl-user::->

符号也可以不在包中,因此可以有许多同名的不同符号并且没有包。

CL-USER 2 > '#:->
#:->

CL-USER 3 > (describe *)

#:-> is a SYMBOL
NAME          "->"
VALUE         #<unbound value>
FUNCTION      #<unbound function>
PLIST         NIL
PACKAGE       NIL

CL-USER 4 > '->
->

CL-USER 5 > (describe *)

-> is a SYMBOL
NAME          "->"
VALUE         #<unbound value>
FUNCTION      #<unbound function>
PLIST         NIL

一个典型的问题:

一个具有测试具有特定符号的事物的 EQ 的功能FOO。用户输入FOO

但是您的 Lisp 函数如何将用户输入转换为符号?符号将在哪个包中?请记住符号因名称和包装而异。如果不指定包,则默认为变量的值CL:*PACKAGE*。但是这个变量在不同的时间可以有不同的值。

只需扩展您的测试功能以打印符号的包,您就会看到不同之处。

CL-USER 7 > (package-name (symbol-package '->))
"COMMON-LISP-USER"
于 2014-01-27T07:53:21.227 回答