Làm cách nào để tôi có thể tạo macro Clojure hoạt động như một hàm, vì vậy tôi có thể chuyển macro đó thành một đối số chẳng hạn? Tôi mong đợi phải quấn nó bằng cách nào đó. Tôi không mong đợi phiên bản gói để hành xử chính xác giống như macro gốc (sự khác biệt của cuộc gọi theo tên so với cuộc gọi theo giá trị), nhưng nó sẽ hữu ích trong một vài trường hợp mà điều này không quan trọng.Xử lý macro Clojure làm chức năng
Trả lời
Nếu tôi hiểu bạn một cách chính xác, bạn chỉ có thể bọc nó trong một hàm.
Xem xét việc này (ngớ ngẩn) thực hiện một chức năng bình phương như một macro:
(defmacro square [x]
(list * x x))
Đi qua nó trực tiếp như một arg sẽ không hoạt động, như bạn đã biết:
user=> (map square [1 2 3 4 5])
java.lang.Exception: Can't take value of a macro: #'user/square (NO_SOURCE_FILE:8)
Nhưng gói nó trong một chức năng sẽ thực hiện thủ thuật:
user=> (map #(square %) [1 2 3 4 5])
(1 4 9 16 25)
Hoặc (và hơi xấu hơn một chút), bạn có thể thực hiện một macro khác để làm một gói chung chung hơn:
(defmacro make-fn [m]
`(fn [& args#]
(eval `(~'~m [email protected]#))))
user=> (map (make-fn square) [1 2 3 4 5])
(1 4 9 16 25)
Tôi muốn gắn bó với gói chức năng bình thường và bỏ qua lần hack cuối cùng này! :)
Có macro nguy hiểm, không dùng nữa mà bạn không bao giờ nên sử dụng. :-P
http://clojure.github.com/clojure-contrib/apply-macro-api.html
Hm, điều này mang lại cho tôi một chồng tràn bộ nhớ khi tôi cố gắng ví dụ này trong Clojure 1.2: (? Áp dụng vĩ mô hoặc [đúng false false])) – pauldoo
Ugh đó là sự thật, vấn đề là với chức năng lan truyền tin trong ns áp dụng-macro: nó là một bản sao của một clojure.core lỗi thời, nếu bạn thay thế nó bằng phiên bản thực tế [công việc hack] (https://gist.github.com/986321) – jneira
Sự khác biệt là tò mò (phần còn lại [1]) ->(), (tiếp theo [1]) -> nil. Đầu tiên với nil? như là vị ngữ bảo vệ để dừng đệ quy làm tăng stackoverflow. – jneira
Đối với macro điên make-fn, cách bên dưới? Nó cũng hoạt động tốt và hy vọng dễ hiểu hơn.
(defmacro make-fn [m]
`(fn [& args#]
(eval
(cons '~m args#))))
- 1. Macro clojure là chức năng/'Một phần' cho Macros?
- 2. Các chức năng nội dòng và các macro tiền xử lý
- 3. Chức năng phối hợp Clojure
- 4. Chức năng Clojure Literals
- 5. Hết giờ chức năng đa xử lý
- 6. chức năng Freemarker vs macro
- 7. Chức năng Matlab xử lý không gian làm việc shenanigans
- 8. MATLAB- chuyển một tham số xử lý chức năng vào một hàm khác làm xử lý
- 9. Macro được đề xuất để thêm chức năng vào hàm tạo dấu gạch ngang của Clojure?
- 10. Macro tiền xử lý C xác định Macro
- 11. Clojure # = macro đọc
- 12. Chức năng Clojure cho Emacs?
- 13. Macro đa dòng tiền xử lý
- 14. Macro Clojure khác với macro C như thế nào?
- 15. Đếm các macro tiền xử lý
- 16. Macro Condj Clojure-New?
- 17. Xác định bên ngoài Macro tiền xử lý trong GLSL
- 18. macro Scala gán param chức năng deconstructed
- 19. Tôi làm cách nào để xử lý mã Clojurescript bắt buộc từ các macro Clojurescript?
- 20. Knockout ràng buộc xử lý chức năng teardown?
- 21. Không tạo các chức năng riêng biệt thay vì một chức năng xử lý chậm nhất?
- 22. Matlab - Kiểm tra xem chức năng xử lý là một chức năng hoặc chức năng cụ thể
- 23. Xử lý luận linh hoạt trong Mathematica chức năng
- 24. Nội bộ V8 - Xử lý các chức năng ẩn danh
- 25. Làm tổ số # /% trong các macro clojure
- 26. Định nghĩa macro giống chức năng trong C
- 27. jquery trống chức năng và sự kiện xử lý
- 28. Các "xử lý" chức năng và Real World Haskell
- 29. clojure chức năng trì hoãn thực hiện
- 30. Cơ sở dữ liệu Lập trình chức năng ở Clojure
Hm, điều này không hoạt động đối với các macro biến thể: người dùng => (áp dụng # (hoặc%) [true false false]) java.lang.IllegalArgumentException: Số lượng sai số args (3) được chuyển đến: người dùng $ eval3 $ fn (NO_SOURCE_FILE: 0) – pauldoo
3 điểm: (1) cách tốt nhất để giải quyết ví dụ này là '(một số danh tính [true false false])', (2) nếu bạn biết số tham số & làm rõ, nó ' sẽ làm thủ thuật: '(áp dụng # (hoặc% 1% 2% 3) [true false false])', (3) hacky 'make-fn' hoạt động:' (áp dụng (make-fn hoặc) [true false false]) ' – trptcolin