Bil*_*osa 0 lisp clisp sbcl common-lisp
这个问题是关于sbcl - 或者我最初想的.问题:角色什么时候不是角色?请考虑以下代码:
(defconstant +asc-lf+ #\Newline)
(defconstant +asc-space+ #\Space)
(prin1 (type-of #\Newline )) (terpri)
(prin1 (type-of #\Space )) (terpri)
(prin1 (type-of +asc-lf+ )) (terpri)
(prin1 (type-of +asc-space+)) (terpri)
Run Code Online (Sandbox Code Playgroud)
正如所料,它产生:
STANDARD-CHAR
STANDARD-CHAR
STANDARD-CHAR
STANDARD-CHAR
Run Code Online (Sandbox Code Playgroud)
现在考虑这段代码:
(defun st (the-string)
(string-trim '(#\Newline #\Space) the-string))
(princ "\"")
(princ (st " abcdefgh "))
(princ "\"")
(terpri)
Run Code Online (Sandbox Code Playgroud)
它产生:
"abcdefgh"
Run Code Online (Sandbox Code Playgroud)
但请考虑以下代码:
(defconstant +asc-lf+ #\Newline)
(defconstant +asc-space+ #\Space)
(defun st (the-string)
(string-trim '(+asc-lf+ +asc-space+) the-string))
(princ "\"")
(princ (st " abcdefgh "))
(princ "\"")
(terpri)
Run Code Online (Sandbox Code Playgroud)
当您使用sbcl加载它时,它会为您提供:
While evaluating the form starting at line 6, column 0
of #P"/u/home/sbcl/experiments/type-conflict.d/2.lisp":"
debugger invoked on a TYPE-ERROR:
The value
+ASC-LF+
is not of type
CHARACTER
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [RETRY ] Retry EVAL of current toplevel form.
1: [CONTINUE] Ignore error and continue loading file "/u/home/sbcl/experiments/type-conflict.d/2.lisp".
2: [ABORT ] Abort loading file "/u/home/sbcl/experiments/type-conflict.d/2.lisp".
3: Exit debugger, returning to top level.
((FLET SB-IMPL::TRIM-CHAR-P :IN SB-IMPL::GENERIC-STRING-TRIM) #\ )
0]
Run Code Online (Sandbox Code Playgroud)
起初,我期待能够报告clisp #'string-trim对预期的返回值进行适当的调用,或者可能出错.但它没有这些.该函数返回传递给它的相同字符串,没有任何修剪.
这应该发生什么?我错过了什么?
编辑约.2017-10-21 08:50 UTC
PuercoPop的精彩答案激发了一个后续问题.如果我将这个问题作为一个单独的问题发布,那就说出来吧.
为什么(至少用sbcl和clisp)这个:
(defconstant +asc-lf+ #\Newline)
(defconstant +asc-space+ #\Space)
(prin1 (type-of (first (list #\Newline #\Space))))
(terpri)
(prin1 (type-of (first '(#\Newline #\Space))))
(terpri)
Run Code Online (Sandbox Code Playgroud)
收益呢?
STANDARD-CHAR
STANDARD-CHAR
Run Code Online (Sandbox Code Playgroud)
在PuercoPop的回答中,我希望它能为第二个表达式产生关于符号而不是字符的东西.
主要的困惑来自于
(+ a b)是代码,这里是函数调用.这两个(quote (+ a b))和'(+ a b)是数据,因为他们评估到引用的文字数据.#\newline已被读作字符对象.它是内置语法:Sharpsign Backslash它不是一个字符串,不是一个符号,也不是一些未知的数据.它被读作一个字符类型的对象(我在这里使用措辞字符对象,也可以说字符).这些是符号:
foo
bar
+foo+
*the-foo*
Run Code Online (Sandbox Code Playgroud)
当符号得到评估时,它们会评估它们的值.
这些是角色对象:
#\f
#\O
#\o
#\newline
Run Code Online (Sandbox Code Playgroud)
当评估角色对象时,他们会评估自己.因此'#\foo,(quote #\foo)并#\foo评估所有相同的对象.
这些是清单
(newline #\newline) ; the first item is a symbol, the second a character object
(#\a #\b #\c) ; a list of character objects
(a b c) ; a list of symbols
Run Code Online (Sandbox Code Playgroud)
如果我们评估列表会发生什么:
(+ a b) ; the sum of the values of A and B
(list a b) ; a list gets computed, with the values of variables a and b
(list 'a 'b) ; a list gets computed, with the symbols A and B
'(a b) ; a literal list of the symbols A and B
'(#\a #\b) ; a literal list of the character objects #\a and #\b
'(a #\a) ; a literal list of the symbol A and the character object #\a
(#\a #\b) ; an error, #\a is not a function/macro/special-form
(+ a 'b) ; an error, a symbol B is not a number
Run Code Online (Sandbox Code Playgroud)
评估反引用列表:
`(a ,a #\a ,#\a) ; a list of the symbol a, the value of the variable a,
; the character object a and again the character object a
Run Code Online (Sandbox Code Playgroud)
你的错误:
'(+asc-lf+ +asc-space+) 评估符号列表.
该函数STRING-TRIM需要一系列字符.
你需要写这样的东西:
(list +asc-lf+ +asc-space+) ; calling the function list
`(,+asc-lf+ ,+asc-space+) ; a backquoted list with comma for evaluation
(vector +asc-lf+ +asc-space+) ; the constructed vector is also a sequence
Run Code Online (Sandbox Code Playgroud)
也:
(list #\Newline #\Space)并'(#\Newline #\Space)评估两个字符列表.该#\语法是Lisp语言的内置功能阅读器构建的角色对象.因此#\newline在读取时转换为字符对象:
CL-USER 82 > (describe (read))
#\Newline ; we type the nine characters #\Newline
#\Newline is a CHARACTER
Name "Newline"
Code 10
Run Code Online (Sandbox Code Playgroud)
问题是你引用了"字符列表".因此,它不是字符列表,而是符号列表.那是
(defun st (the-string)
(string-trim (list +asc-lf+ +asc-space+) the-string))
Run Code Online (Sandbox Code Playgroud)
当它说时,错误消息暗示了这一点
值+ ASC-LF +不是CHARACTER类型
并不是
值#\ Newline不是CHARACTER类型
| 归档时间: |
|
| 查看次数: |
262 次 |
| 最近记录: |