2012-12-11 32 views
16

Tôi không hiểu mã này từ số clojure 1.5 release notes. Nó sử dụng macro cond->. Ví dụ, làm thế nào nó sẽ dịch thành mã trước 1.5?Macro Condj Clojure-New?

user=> (cond-> 1 
       true inc 
       false (* 42) 
       (= 2 2) (* 3)) 
6 
+0

bạn đã tìm thấy điều đó ở đâu? – mishadoff

+0

Tại một dự đoán tôi sẽ tưởng tượng điều này cho 6 = '(* 3 (inc 1))', nơi nó đề tài đối số đầu tiên thông qua bất kỳ hàm nào có biến vị ngữ ước tính là đúng. – cobbal

+1

https://github.com/clojure/clojure/blob/master/changes.md#24-new-threading-macros –

Trả lời

27

Mỗi bước thay đổi kết quả nếu thử nghiệm là đúng hoặc để riêng nó nếu thử nghiệm là sai.

Bạn có thể viết này trong 1,4 bằng cách luồn các chức năng ẩn danh:

user> (-> 1 (#(if true (inc %) %)) 
      (#(if false (* % 42) %)) 
      (#(if (= 2 2) (* % 3) %))) 
6 

Mặc dù cond-> không giới thiệu chức năng mới, thay vào đó nó sẽ tạo ra một hình thức ràng buộc để có hiệu quả hơn:

user> (let [g 1 
      g (if true (inc g) g) 
      g (if false (* g 42) g) 
      g (if (= 2 2) (* g 3) g)] 
     g) 
6 

và sử dụng số gensym cho g trong một số biểu mẫu sử dụng ký hiệu g


cond->> rất giống nhau, nó chỉ đặt biểu tượng chuỗi ở một vị trí khác.

user> (let [g 1 
      g (if true (inc g) g) 
      g (if false (* 42 g) g) 
      g (if (= 2 2) (* 3 g) g)] 
     g) 
6 

mà trong ví dụ này sẽ cho kết quả tương tự vì *+ là giao hoán.

+0

Tôi thích ví dụ ở giữa rất ... rất nhiều. Điều đó làm cho nó rõ ràng hơn rất nhiều. – Zchpyvr

+0

Ngoài ra, tôi giả định rằng macro 'cond - >> 'thực hiện một thói quen tương tự? – Zchpyvr

+0

xin lỗi, tôi đã chỉnh sửa nó trong khi bạn nhận xét, đó là giữa? –