Tôi đang cố gắng (như một bài tập tự học) để tạo một macro Clojure sẽ tạo mã để áp dụng một hàm cho một dãy số nguyên và tổng kết quả, ví dụ:Kiểm soát việc tạo biểu tượng trong các macro Clojure
f (0) + f (1) + f (2) + f (3)
Đây là nỗ lực của tôi:
(defmacro testsum [func n]
`(fn [x#] (+ [email protected](map (fn [i] `(~func x#)) (range n)))))
Tuy nhiên cái gì đó dường như đi sai với x # gensym và tôi kết thúc với hai phiên bản khác nhau của x và do đó chức năng không hoạt động:
(macroexpand '(testsum inc 3))
cho:
(fn* ([x__809__auto__]
(clojure.core/+
(inc x__808__auto__)
(inc x__808__auto__)
(inc x__808__auto__))))
Đây chính xác là những gì tôi muốn tách biệt với các phiên bản 809 và 808 khác nhau của x .....
Tôi đang làm gì sai? Tôi nghĩ rằng gensym tự động có nghĩa là để tạo ra một biểu tượng duy nhất cho chính xác loại mục đích này? Có cách nào tốt hơn để làm điều này?
Như một suy nghĩ, cũng có thể thay thế '(gensym" x ")' bằng '\' x # ', mặc dù tôi chưa bao giờ thấy ai làm điều đó cho một gensym được tạo rõ ràng bên ngoài hình thức tạo ra mở rộng chính. –
Tuyệt vời Michal - hoạt động hoàn toàn cảm ơn rất nhiều! Vẫn nhận được đầu của tôi xung quanh các biểu tượng sau khi đến từ một thế giới Java .... – mikera