簡體   English   中英

此JavaScript代碼的ClojureScript等效項

[英]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回報一個太)當一些呼叫,只能判斷doalldorundoseq他們。

如果您調用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM