一个口齿不清的问题在过去的几个月里,我一直在慢慢地学习lisp,在尝试从web浏览器获取输入和从REPL获取输入时遇到了一个问题。
具体问题是,在尝试计算此代码时:
假设sexp'(look north)
(member (car sexp) '(look walk pickup drop))
从SBCL中的REPL来看,这工作正常,如预期的那样然而,当从hunchentoot抓取sexp时,即使sexp“看起来”与从REPL抓取的(car sexp)相同,它似乎永远无法考虑'(look walk pickup drop)的成员的结果。
我认为这可能是文件的字符编码,而不是从web浏览器抓取时的字符编码,但我不知道如何检验这个假设任何指点都非常感谢!
编辑
我接受输入的方式基于conrad barski的文本冒险游戏《lisp之地》,具体如下。

(defun game-read (string-to-read)
  (let ((cmd (read-from-string
               (concatenate 'string "(" string-to-read ")"))))
    (describe cmd)
    (flet ((quote-it (x)
                     (list 'quote x)))
      (cons (car cmd) (mapcar #'quote-it (cdr cmd))))))

然后包装在:
(defun game-eval (sexp)
  (if (member (car sexp) *allowed-commands*) ;Offending line
      (eval sexp)
      '(i do not know that command.)))

其中sexp是:
(defparameter *allowed-commands* '(look walk pickup inventory))

我已经标记为冒犯正常工作的行,但是当*allowed-commands*来自作为请求的一部分从hunchentoot获取的请求参数时,string-to-read看起来与我知道如何看待它相同,但在(car sexp)中找不到。

最佳答案

你需要确定你得到的是什么它是一个符号吗Common Lisp具有TYPE-OF、INSPECT和descripe等函数来获取有关数据的更多信息。

* (describe 'north)

COMMON-LISP-USER::NORTH
  [symbol]


* (type-of 'north)

SYMBOL

下一个问题是:如果它是一个符号,它在哪个包里?
* (symbol-package 'north)

#<PACKAGE "COMMON-LISP-USER">

你的其他符号在同一个包裹里吗?
下一个问题是:如果它是一个符号或字符串,那么大写如何?
* (symbol-name 'north)

"NORTH"

默认情况下,符号为大写从输入中读取符号不需要这样。
现在还可以使用MEMBER进行纯字符串比较:
* (member (symbol-name '|Foo|)
          '(foo bar baz)
          :key #'symbol-name :test #'equalp)

(FOO BAR BAZ)   ; this is the usual return value,
                ; the rest list with first item found

10-06 09:56