2015-11-02 18 views
6

Trong Common Lisp, tôi có thể xác định và sử dụng một macro để chụp một biến từ phạm vi từ vựng, để tôi có thể sử dụng nó trong một hình thức let:Cách chụp trong phạm vi từ vựng trong macro Clojure?

CL-USER> (defmacro plus9() `(+ 9 woo)) 
PLUS9 
CL-USER> (macroexpand '(plus9)) 
(+ 9 WOO) 
T 
CL-USER> (let ((woo 1)) (plus9)) 
10 

Tuy nhiên, khi tôi định nghĩa một macro tương tự trong Clojure, nó đang tìm kiếm một định nghĩa của woo trong không gian tên user:

user=> (defmacro plus9 [] `(+ 9 woo)) 
#'user/plus9 
user=> (macroexpand '(plus9)) 
(clojure.core/+ 9 user/woo) 
user=> (let [woo 1] (plus9)) 

CompilerException java.lang.RuntimeException: No such var: user/woo 

rõ ràng tôi là sự hiểu lầm như thế nào phạm vi hoạt động trong Clojure. Cách chính xác để đạt được vĩ mô này với Clojure là gì?

+1

http://hubpages.com/technology/Unhygenic-anaphoric-Clojure-macros-for-fun-and-profit – coredump

+1

Cú pháp trích dẫn trong Clojure được thiết kế đặc biệt để * tránh các va chạm * của các tên biểu tượng được trích dẫn với các tên có phạm vi từ vựng, trên lý thuyết cho rằng chúng thường không được mong đợi. Như minh họa trong câu trả lời, bạn phải làm thêm công việc nếu đó là những gì bạn đang cố gắng làm. – Alex

Trả lời

8

tôi là một Noob vĩ mô, nhưng làm thế nào về

user=> (defmacro plus9 [] `(+ 9 ~'woo)) 
#'user/plus9 
user=> (macroexpand '(plus9)) 
(clojure.core/+ 9 woo) 
user=> (let [woo 1] (plus9)) 
10 
+3

Vâng. đó là cách bạn sẽ nắm bắt một ràng buộc từ vựng trong clojure. cú pháp-trích dẫn sẽ hội đủ điều kiện biểu tượng theo không gian tên, do đó đảm bảo vệ sinh. Vì lý do đó, '~ '' được coi là một mã nguồn và thành ngữ, bạn sẽ chuyển biểu tượng được chụp tới macro: '' '(defmacro plus9 [sym]' (+ 9 ~ sym)), (hãy để [x 1] (cộng9 x)) '' ' – Bendlas

Các vấn đề liên quan