我正在尝试在我的ClojureScript代码中使用esrecurse,我有一个看起来像这样的JavaScript代码片段
esrecurse.visit(ast, {
Literal: console.log
});
我正在努力想出ClojureScript的等价物,但每当我运行它esrecurse.visit
时都不会被称为
#(.visit esrecurse % (js-obj "Literal" (fn [node] node)))
其中%
是AST。老实说,我不确定我做错了什么,我也试过以不同的方式传递第二个参数,比如
#(.visit esrecurse (first (vals %)) {:Literal (fn [node] node)})
没有成功。
我正在调用此{/ 1}}
mutate?
但是对于这个版本和我的版本我仍然没有得到任何东西,我也尝试传递(defn mutate?
"applies a mutation to the ASTs,
returns the mutated, or non mutated, ASTs"
[asts]
(map
#(.visit esrecurse % #js {:Literal print})
asts))
(mutate? (reader/to-ast (reader/read "./test/example-project/lib")))
而不是identity
,但我得到print
作为结果。
答案 0 :(得分:1)
对于我来说,esrecurse.visit
。
(defn visit [ast]
(.visit esrecurse ast #js {:Literal print}))
(visit #js {:type "Literal"})
;; prints #js {:type "Literal"}
模拟代码:
var esrecurse = {
visit(node, visitor) {
visitor.Literal(node);
}
}
这是同一个想法的一个不那么冗长的版本。
#(.visit esrecurse % #js {:Literal print}))
验证您是否正确调用了该函数,因为您的第一个实现对我来说很合适并且可以替代上述任一函数。
猜测一下,我说你在第二个例子中没有看到任何事情的原因是因为Clojure的序列是 lazy - 意味着你的计算赢了&直到你要求结果才会被应用。
这些懒惰的序列(take
也返回一个)仅在某些内容调用doall
,dorun
或doseq
时进行评估。
如果您调用print
或评估在repl中返回延迟序列的表达式,则会发生这种情况。
您可以尝试使用doall
强制评估您的懒惰表达式。
(doall
(mutate? (reader/to-ast (reader/read "./test/example-project/lib"))))
这并不自然,这是重点。作为一种相当纯粹的函数式编程语言,Clojure希望你能够主要编写没有副作用的函数。
这是一个JavaScript互操作可能会很痛苦的示例,因为esrecurse.visit
实际上没有返回值,因此调用map
会返回一系列nil
值。我很想把匿名函数拉出来并重新定义它以便总是返回它传递的AST。
(defn visit [ast]
(.visit esrecurse ast #js {:Literal print})
ast)
(defn mutate?
"applies a mutation to the ASTs,
returns the mutated, or non mutated, ASTs"
[asts]
(map visit asts))
(doall
(mutate? (reader/to-ast (reader/read "./test/example-project/lib"))))
就像抬头一样,mutate?
将是命名一个返回布尔值的函数的约定。也许你的意思是mutate!
,这可能是一个可能会产生副作用的函数的惯例?