[英]ClojureScript equivalent for this JavaScript code
我正在嘗試在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)})
沒有成功。
我正在調用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
但是結果是(nil)
。
這對esrecurse.visit
實現對我來說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的序列是惰性的 -意味着在您請求結果之前不會應用計算。
這些懶惰的序列( 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!
取而代之的是,可能會產生副作用的功能的慣例是什么?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.