Điều này tương tự như vấn đề được thảo luận trong Treat Clojure macro as a function nhưng khi thử cách tiếp cận trong câu trả lời hàng đầu, tôi gặp lỗi. Hy vọng quá nhiều thông tin về ứng dụng cụ thể của tôi là không cần thiết, bởi vì nó là khá phức tạp, nhưng đây là một phiên bản cất những gì tôi đã cố gắng để làm:Macro clojure là chức năng/'Một phần' cho Macros?
(defmacro make-fn [m arg1]
`(fn [& args#]
(eval `(~'~m ~'~arg1 [email protected]#))))
Tôi đã sử dụng macro trong bối cảnh này:
(let [columns (make-columns table-width)
table-name (keyword (str "table_" n))]
(apply (make-fn helpers/tbl table-name) columns))
"người trợ giúp/tbl" là macro dự kiến một từ khóa tên bảng và một số biến danh sách chứa thông số cột (như [: varchar 100] hoặc một cái gì đó). Tôi đang cố gắng để tạo ra các thông số kỹ thuật bảng cơ sở dữ liệu ngẫu nhiên trên bay để tạo thuận lợi cho một số thử nghiệm. Dù sao, khi cố gắng thực thi mã trên, tôi nhận được lỗi sau:
CompilerException java.lang.RuntimeException: Unable to resolve symbol: table-name in this context, compiling:(NO_SOURCE_PATH:1)
tôi loại nắm bắt các vấn đề: mở rộng vĩ mô được thực hiện tại thời gian biên dịch, và tôi đang cố gắng để bao gồm một giá trị thời gian chạy trong macro mở rộng, do đó việc sử dụng lẻ trích dẫn và unquoting để có được tất cả mọi thứ thiết lập vừa phải. Về cơ bản, tôi muốn một phần cho các macro và tôi cần có khả năng sử dụng lại cơ chế này cho các macro khác nhau trong các không gian tên khác nhau và có tất cả độ phân giải biến xuất hiện đúng. Điều này thậm chí có thể?
BTW , thực tế thú vị về 'cú pháp trích dẫn': nó được thực hiện hoàn toàn trong trình đọc. Khi người đọc thấy một backtick, nó đọc dạng sau, sau đó biến nó đệ quy thành mã sử dụng 'seq',' concat' và 'list'. Trình biên dịch chỉ thấy mã 'concat' /' list' kết quả. –