为什么 Guile 中的表达式无法用 car 作为调用函数?
数据小陈
结论
在 Guile 的 Scheme 中,((car '(car)) '(a b)) 不会返回 a。(car '(car)) 得到的是符号 car,而不是 car 过程。Scheme 接着会尝试把这个符号当作函数调用,于是报错 Wrong type to apply: car。
表达式是怎样求值的
引号会阻止后面的表达式被求值。'(car) 是 (quote (car)) 的简写,表示一个只含符号 car 的列表。
外层表达式的求值过程如下:
- 先求值运算符位置上的表达式
(car '(car))。 car从列表(car)中取出第一个元素,得到符号car。- Scheme 尝试把这个结果当作过程,应用到参数
'(a b)上。 - 这个结果是符号,不是过程,所以调用失败。
原表达式中的 '(a b) 是作为数据传入的列表。要取出它的第一个元素,可以直接写:
(car '(a b))
;; => a
如果要在运算符位置取出过程
要让 (car ...) 返回过程本身,可以这样写:
((car (list car)) '(a b))
;; => a
这里的 car 没有加引号,因此会求值为 car 过程。(list car) 创建一个包含该过程的列表,外层的 car 从列表中取出过程并调用它。
未加引号的 car 作为标识符会求值为过程;'car 表示的是符号 car。符号不会因为名称与过程相同,就自动变成该过程。
备注:内容仅供参考。
