在Clojure REPL中,这个表达式
( #(for [x %] (+ 100 (second x))) ['(+ 38) '(+ 48)] )如预期的那样产生(138 148)
但是这个
( #(for [x %] ((first x) 100 (second x))) ['(+ 38) '(+ 48)] )产生(38 48),这似乎很奇怪。
这两个表达式真的应该产生相同的结果! 我错过了什么? 将欣赏任何想法来解决这个谜。
顺便说一句,我试着用'apply(first x)'并将其余的参数打包到一个列表中,但它似乎并不重要。 同样的意外结果又回来了。
另外,为了验证+确实可以从输入中解析出来,我给了REPL以下内容
( #(for [x %] (resolve (first x) )) '((+ 38) (+ 48)) )其中产生
(#'clojure.core/+ #'clojure.core/+) as expected.At the Clojure REPL, this expression
( #(for [x %] (+ 100 (second x))) ['(+ 38) '(+ 48)] )produces (138 148) as expected
but this
( #(for [x %] ((first x) 100 (second x))) ['(+ 38) '(+ 48)] )produces (38 48) which seems truly weird.
Both expressions really should be producing the same result! What am I missing? Will appreciate any ideas to resolve this mystery.
BTW, I tried to use 'apply (first x)' and package the rest of the args into a list but it doesn't seem to matter. The same unexpected result comes back.
Also, to verify that the + indeed gets resolved from the input, I gave the following to the REPL
( #(for [x %] (resolve (first x) )) '((+ 38) (+ 48)) )which produced
(#'clojure.core/+ #'clojure.core/+) as expected.最满意答案
( #(for [x %] ((first x) 100 (second x))) ['(+ 38) '(+ 48)] )在这里+是一个符号,而不是一个函数,因为它已经在列表中引用。 但是,符号被定义为在作为函数调用时进行地图查找(与关键字相同)。 所以('+ 100 38)和(get 100 '+ 38) 。 最后一个论点是“如果在地图中找不到我想要的东西,请返回”。 由于100不是地图,所以+使用该参数作为返回值。
为了让它做你想做的事情,你有两个选择:
使用矢量而不是引用列表可以确保+得到适当的解决。
( #(for [x %] ((first x) 100 (second x))) [[+ 38] [+ 48]] )自己解决它,以确保您使用+功能而不是+符号。
( #(for [x %] ((resolve (first x)) 100 (second x))) ['(+ 38) '(+ 48)] ) ( #(for [x %] ((first x) 100 (second x))) ['(+ 38) '(+ 48)] )In this the + is a symbol, not a function, because it has been quoted in the list. However, symbols are defined as doing map lookup when invoked as a function (the same as keywords). So ('+ 100 38) is the same as (get 100 '+ 38). That last argument is the "if you can't find what I want in the map, return that". Since 100 is not a map, + uses that argument as the return value.
To make it do what you want you have two options:
Use vectors instead of quoted lists ensures that + gets resolved appropriately.
( #(for [x %] ((first x) 100 (second x))) [[+ 38] [+ 48]] )Resolve it yourself to ensure that you use the + function instead of the + symbol.
( #(for [x %] ((resolve (first x)) 100 (second x))) ['(+ 38) '(+ 48)] )更多推荐
发布评论