#\、' 和 #' 之间有什么区别?

What is the difference between #\ , ' and #'?

在Common Lisp中,假设“a”只是一个字符,#\a'a#'a有什么区别?

我的问题来自 tutorialspoint.com Lisp 教程。本教程在某一时刻介绍了:

; a character array with all initial elements set to a
; is a string actually
(write(make-array 10 :element-type 'character :initial-element #\a)) 
(terpri)

; a two dimensional array with initial values a
(setq myarray (make-array '(2 2) :initial-element 'a :adjustable t))
(write myarray)
(terpri)

输出:

"aaaaaaaaaa"
#2A((A A) (A A))

#' 未包含在此示例中,但我将其包含在问题中,因为它也可能令人困惑。

非常感谢!

首先,a 不是“只是一个字符。”Lisp reader 将 #\a 解析为字符文字 a,这是Common Lisp中的一个对象。注意 #\a#\A 是不同的字符对象。

当 Lisp reader 遇到单引号时,不会对单引号后面的表达式求值。具体来说,'a 被视为 (quote a),其中 quote returns 其参数未计算。现在,a 是一个 符号 ,因此 'a 计算为该符号。但是 Lisp reader 默认情况下将它读取的大多数字符大写,所以 'a 实际上计算为符号 A。好消息是,无论你输入 a 还是 A,Lisp reader 都会读作 A(除非你弄乱了可读表),而且两者都是 'a'A 计算出符号 A.

当 Lisp reader 遇到 #'a 时,整个表达式被视为 (function a),当评估 returns 与名称 [=12= 关联的函数时].但是,请注意,在不表示函数的标识符上使用 function 并扩展为 #' 是错误的。

为了澄清最后一部分,请考虑以下 REPL 交互:

CL-USER> (defvar a 1)
A
CL-USER> a
1
CL-USER> #'a

The function COMMON-LISP-USER::A is undefined.
   [Condition of type UNDEFINED-FUNCTION]

这里定义了变量 a 并赋值 1,但是当我们尝试访问 a 表示的函数时,我们得到一条错误消息,因为没有这样的功能。继续:

; Evaluation aborted on #<UNDEFINED-FUNCTION A {1002DDC303}>.
CL-USER> (defun a (x) x)
A
CL-USER> (a 'b)
B
CL-USER> a
1
CL-USER> #'a
#<FUNCTION A>

现在我们已经定义了一个名为 a 的函数,它只是 returns 它的参数。您可以看到,当我们使用参数 'b 调用 a 时,我们得到了预期的结果:(a 'b) --> b。但是,当我们单独计算 a 时,我们仍然得到 1。 Common Lisp 中的符号是具有值单元和函数单元等单元的对象。经过上述交互后,符号 a 现在在其值单元格中具有 1,并且它具有我们在其函数单元格中定义的函数。当计算符号 a 时,访问值单元格,但当计算 (function a)#'a 时,访问函数单元格。你可以在上面看到当 #'a 被评估时,我们定义的函数被返回,并且 REPL 打印 #<FUNCTION A> 来显示这一点。

顺便说一句,我不推荐使用 Tutorialspoint 来学习 Common Lisp。浏览网站,我马上看到了这个:

LISP expressions are case-insensitive, cos 45 or COS 45 are same.

这是完全错误的。而且,Lisp 并不是全部大写的。 None 这激发了信心。相反,找一本好书。 tag-info 页面上有一些建议。

#\

这里介绍一个人物

CL-USER> #\a
#\a
CL-USER> (character 'a)
#\A
CL-USER> (character "a")
#\a

'

这是quote,引用而不是评估事物和构造对象文字。

CL-USER> a 
=> error: the variable a is unbound.

CL-USER> 'a
A

CL-USER> (inspect 'a)

The object is a SYMBOL.
0. Name: "A"
1. Package: #<PACKAGE "COMMON-LISP-USER">
2. Value: "unbound"
3. Function: "unbound"
4. Plist: NIL
>  q

CL-USER> (equal (list 1 2) (quote (1 2))) ;; aka '(1 2)
T ;; but watch out with object literals constructed with quote, prefer constructor functions.

and #'

这是引用函数的 sharpsign-quote。

CL-USER> #'a
=> error: The function COMMON-LISP-USER::A is undefined.

CL-USER> (defun a () (print "hello A"))
A
CL-USER> (a)
"hello A" 
"hello A"

CL-USER> #'a
#<FUNCTION A>

CL-USER> (function a)
#<FUNCTION A>

可以请 Lisp 描述您提到的数据对象。

如果我们看一下表达式:

CL-USER 13 > (dolist (object (list '#\a ''a '#'a))
              (terpri)
              (describe object)
              (terpri))


#\a is a CHARACTER
Name      "Latin-Small-Letter-A"
Code      97


(QUOTE A) is a LIST
0      QUOTE
1      A


(FUNCTION A) is a LIST
0      FUNCTION
1      A
NIL

如果我们查看 计算的 表达式:

CL-USER 5 > (dolist (object (list #\a 'a #'a))
              (terpri)
              (describe object)
              (terpri))


#\a is a CHARACTER
Name      "Latin-Small-Letter-A"
Code      97


A is a SYMBOL
NAME          "A"
VALUE         #<unbound value>
FUNCTION      #<interpreted function A 422005BD54>
PLIST         NIL
PACKAGE       #<The COMMON-LISP-USER package, 73/256 internal, 0/4 external>


#<interpreted function A 422005BD54> is a TYPE::INTERPRETED-FUNCTION
CODE      (LAMBDA (B)
           A)