为什么Clojure中的list*仅适用于尾部位置的向量?

为什么Clojure中的list*仅适用于尾部位置的向量?,clojure,Clojure,我是个新手。我正在尝试玩repl,我看到了以下输出。我不太明白为什么他们的行为如此不同 (def a (list 1 2 3)) =>#'test.core/a (list* 4 5 a) =>(4 5 1 2 3) (list* a 4 5) =>IllegalArgumentException Don't know how to create ISeq from: java.lang.Long clojure.lang.RT.seq

我是个新手。我正在尝试玩
repl
,我看到了以下输出。我不太明白为什么他们的行为如此不同

(def a (list 1 2 3))  =>#'test.core/a

(list* 4 5 a)          =>(4 5 1 2 3)

(list* a 4 5)         =>IllegalArgumentException Don't know how to create ISeq from: java.lang.Long  clojure.lang.RT.seqFrom (RT.java:542)
为什么上述两条语句的行为方式与上述两条语句相同

(list* 4 5 [1 2 3])     =>(4 5 1 2 3)

(list* 4 5 [a])       =>(4 5 (1 2 3))

(list* 4 5 (1 2))     =>ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn  test.core/eval3837 (form-init633779145118520639.clj:1)

有人能解释一下为什么上面的每个语句都有不同的输出吗?

请参见列表*的文档字符串:

创建一个新的seq,其中包含在其余seq前面的项,即最后一个seq 其中的一个将被视为一个序列

注:seq不是一个列表,但列表、向量和其他东西可以被视为序列。当repl处的输出看起来像一个列表时,也有一个seq,它被打印在parens中

所以在第一种情况下,最后一个参数是一个文本向量,它被视为一个序列,得到一个未赋值的序列

在第二种情况下,列表“a”作为文本向量中的单个元素,因此向量被视为序列,但内部列表不是,返回的序列有三个元素:4、5和列表a

在最后一个例子中,lisps中的函数调用语法与列表语法非常相似,这让您大吃一惊。(12)试图调用数字1,就好像它在函数中一样(参数为2)。文字数字不能解释为函数

如果希望列表文字而不是函数调用,则必须引用它:

(list* 4 5 '(1 2)) => (4 5 1 2)

请参见列表*的文档字符串:

创建一个新的seq,其中包含在其余seq前面的项,即最后一个seq 其中的一个将被视为一个序列

注:seq不是一个列表,但列表、向量和其他东西可以被视为序列。当repl处的输出看起来像一个列表时,也有一个seq,它被打印在parens中

所以在第一种情况下,最后一个参数是一个文本向量,它被视为一个序列,得到一个未赋值的序列

在第二种情况下,列表“a”作为文本向量中的单个元素,因此向量被视为序列,但内部列表不是,返回的序列有三个元素:4、5和列表a

在最后一个例子中,lisps中的函数调用语法与列表语法非常相似,这让您大吃一惊。(12)试图调用数字1,就好像它在函数中一样(参数为2)。文字数字不能解释为函数

如果希望列表文字而不是函数调用,则必须引用它:

(list* 4 5 '(1 2)) => (4 5 1 2)
如果您查看和docstring,它将是有意义的

文件说:

创建一个新的seq,其中包含在其余项前面的项,最后一项将被视为序列

我的

在第一个块中,最后一个表达式失败,因为5是最后一个参数,但不是序列

(列表*4 5[1 2 3])
的工作原理与
(列表*4 5 a)
的工作原理相同。最后一个参数是一个序列,正如它所期望的那样。正如您在定义中所看到的,它只是将限制在最后一个参数上

(列表*4 5[a])
给出不同的结果,因为您已将集合
a
包装到另一个集合中。它只是添加到外部集合中,而内部集合则保持不变

(列表*4 5(1 2))
的故障实际上不是一个相关的问题。请记住,只要
(…)
没有引号,它就会尝试对其求值,并希望列表中的第一个元素是可调用的。但是,1不可调用,因此会出现错误。您需要引用它,以将其视为列表文字,而不是要计算的代码

如果您查看和docstring,它将是有意义的

文件说:

创建一个新的seq,其中包含在其余项前面的项,最后一项将被视为序列

我的

在第一个块中,最后一个表达式失败,因为5是最后一个参数,但不是序列

(列表*4 5[1 2 3])
的工作原理与
(列表*4 5 a)
的工作原理相同。最后一个参数是一个序列,正如它所期望的那样。正如您在定义中所看到的,它只是将限制在最后一个参数上

(列表*4 5[a])
给出不同的结果,因为您已将集合
a
包装到另一个集合中。它只是添加到外部集合中,而内部集合则保持不变


(列表*4 5(1 2))
的故障实际上不是一个相关的问题。请记住,只要
(…)
没有引号,它就会尝试对其求值,并希望列表中的第一个元素是可调用的。但是,1不可调用,因此会出现错误。您需要引用它,以将其视为列表文字,而不是要计算的代码

只要我们的目标是建立一个知识库,每个问题都应该有一个明确而有用的标题。如果我们有数千个题为“用[Language-X]解释这个程序的输出”的问题,没有人能在知识库中找到有用的东西(因为他们需要打开每个问题,看看“这个代码”是什么,看看它是否与他们遇到的问题相匹配)。你试过评估
(12)
?我们的目标是建立一个知识库,每个问题都应该有一个独特而有用的标题。如果我们有数千个题为“用[Language-X]解释这个程序的输出”的问题,没有人能在知识库中找到有用的东西(因为他们需要打开每个问题,看看“这个代码”是什么,看看它是否与他们遇到的问题相匹配)。你试过评估
(12)
?我同意为了清晰起见,这改进了我的答案。我很感激你的改进,尽管我很难不觉得你的评论有点屈尊俯就。@AlexStoddard抱歉。老实说,我匆忙地写下了这个答案和评论,因为我已经写下了一半的答案