Clojure Koan第8节,第5节

Clojure Koan第8节,第5节,clojure,lisp,Clojure,Lisp,为什么这是有效的: (= '(:anything :goes :here) (filter (fn [x] true) '(:anything :goes :here))) 但不是这个 (= (:anything :goes :here) (filter (fn [x] true) '(:anything :goes :here))) 或 甚至 (= '(:anything :goes :here) (filter (fn [x] true) (:anything :goes :here))

为什么这是有效的:

(= '(:anything :goes :here) (filter (fn [x] true) '(:anything :goes :here)))
但不是这个

(= (:anything :goes :here) (filter (fn [x] true) '(:anything :goes :here)))

甚至

(= '(:anything :goes :here) (filter (fn [x] true) (:anything :goes :here)))
要筛选的第二个参数是带引号的列表而不是普通列表,这有什么特殊原因吗

user=> (filter (fn [x] true) (:abc :def :ghi))
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword  clojure.lang.RT.seqFrom (RT.java:505)

事实上,我仍然不确定列表何时也是函数调用。这与引用似乎是相关的。是否需要引用所有“普通列表”,除非它们是空列表

计算列表时,第一个元素被假定为函数(或宏或特殊形式)

当列表的第一个元素是函数时,首先计算所有参数,然后将函数应用于结果值

如果列表的第一个元素是宏或特殊形式,则根据宏/特殊形式的不同,可以计算或不计算每个参数

Clojure将对第一个元素为关键字的列表求值,方法是尝试在作为关键字函数参数提供的映射中找到该关键字作为关键字,然后返回相应的值,否则返回下一个参数(如果提供)。因此
(:anything:goes::here)
将返回
here

是一个读取宏,它将其参数放入一个
引号
特殊形式。也就是说,
'任何东西
=>
(引用任何东西)

就你而言:

当计算
=
时,必须计算
(:anything:goes:here)
和/或
”(:anything:goes:here)
的值。对第一个的评估将产生
:here
。(在其他Lisp中,这将导致错误)
'(:anything:goes:here)
(quote(:anything:goes:here))
的缩写形式,
quote
是一种特殊形式,它返回未计算的参数,结果是列表
(:anything:goes:here)
,然后传递给
=
过滤器
,无需进一步计算

在每种情况下发生的是:

(= '(:anything :goes :here) (filter (fn [x] true) '(:anything :goes :here)))
=
正在将
(:anything:go:here)
(:anything:go:here)
进行比较,结果为true

(= (:anything :goes :here) (filter (fn [x] true) '(:anything :goes :here)))
:here
(:anything:goes:here)
进行比较,结果为false

(= (:anything :goes :here) (filter (fn [x] true) (:anything :goes :here)))
(= '(:anything :goes :here) (filter (fn [x] true) (:anything :goes :here)))

在这两种情况下,
filter
应用于单个关键字
:此处
,导致一个错误。

我想值得一提的是,这对几乎所有Lisp都是正确的,而不仅仅是clojureYou有点错<代码>:任何东西都是一个关键字,它被很好地定义为一个函数。请参阅,
invoke(Object,Object)
method。简而言之,它要求其第一个参数自行查找,如果第一个参数可以,如果不能,则默认为标准的
get
函数。在这两种情况下,第二个参数都充当默认值。因此以下表达式:
(:abcd:defg:hijk)
将返回
:hijk
,作为默认值。@Vladimitaveveve感谢您的更正。我现在已经更新了答案。@jozefg将关键字作为函数处理(最初未提及)在其他Lisp中并不常见。@TerjeD。我指的是引用的第一部分
(= (:anything :goes :here) (filter (fn [x] true) (:anything :goes :here)))
(= '(:anything :goes :here) (filter (fn [x] true) (:anything :goes :here)))