2013-02-08 29 views
9

Hãy để chúng tôi nói rằng tôi có một X.clojurescript và một không gian tên X.clojure. Tất cả mọi thứ trong X.clojurescript là mã Clojurescript, mọi thứ trong X.clojure là mã Clojure. Rất tiếc, tôi không thể xác định macro trực tiếp trong Clojurescript, tôi phải xác định macro trong Clojure và sau đó đưa chúng vào không gian tên Clojurescript bằng cách sử dụngTôi làm cách nào để xử lý mã Clojurescript bắt buộc từ các macro Clojurescript?

(ns X.clojurescript.abc 
    (:require-macros [X.clojure.def :as clj])) 

Điều này là tốt. Tuy nhiên, điều gì xảy ra nếu macro (được định nghĩa trong X.clojure) sẽ cần phải tham khảo một cái gì đó được định nghĩa trong một không gian tên Clojurescript (X.clojurescript)? Vấn đề là trình biên dịch Clojure không nhìn vào không gian tên Clojurescript của tôi (một thư mục riêng biệt) khi giải quyết các không gian tên khác.

Tôi đã giải quyết vấn đề này bằng cách tạo một vùng tên trong mã Clojure có cùng không gian tên và định nghĩa cần thiết như tồn tại trong Clojurescript, nhưng điều này có vẻ ngu ngốc. Vì vậy, ví dụ, nếu tôi cần X.clojurescript.abc.y trong macro của tôi, tôi sẽ chỉ tạo ra một không gian tên bổ sung ở phía Clojure để xóa một dummy y trong phiên bản Clojure của tôi là X.clojurescript.abc; loại câm.

Làm cách nào để xử lý macro cần tham chiếu đến nội dung nào đó ở phía Clojurescript?

+0

Tạo macro của bạn sao cho tất cả những thứ bắt buộc từ clojurescript là tham số. Nếu bạn có thể thêm một số mã nó sẽ được dễ dàng hơn nhiều để trả lời truy vấn riêng của bạn – Ankur

+2

Tôi không nghĩ rằng tôi hiểu câu hỏi của bạn. Macro của bạn phải * tạo * mã mà sau đó sẽ được đánh giá bằng clojurescript. Vì vậy, nếu bạn phải tham khảo bất kỳ def clojurescript sẽ không đủ để tạo ra các biểu tượng trong việc mở rộng vĩ mô? – KIMA

+0

'đề cập đến một cái gì đó ở bên Clojurescript' bạn cần rằng tại thời gian mở rộng vĩ mô hoặc điều này sẽ là cái gì đó sẽ được phát ra trong mã đầu ra? – Ankur

Trả lời

6

Thời gian duy nhất một macro cần một không gian tên cụ thể tại thời điểm định nghĩa là nếu macro đang sử dụng mã từ không gian tên đã nói để tạo danh sách các ký hiệu sẽ trả về.

bạn có thể làm theo cùng với những ví dụ trong repl:

(defmacro foo 
    [a] 
    `(bar/bar ~a)) 

định nghĩa của foo sẽ biên dịch mặc dù thanh không là một không gian tên được xác định

(foo :a) 

gọi foo bây giờ sẽ thất bại bởi vì bạn chưa xác định không gian tên thanh hoặc thanh chức năng chưa

(ns bar) 
(defn bar 
    [x] 
    [x x]) 

định nghĩa thanh trong không gian tên thanh

(ns user) 
(foo :a) 

=> [: a: a]

ý rằng thanh không cần phải tồn tại tại thời điểm định nghĩa foo của. Trong thực tế, không gian tên thậm chí không cần phải tồn tại tại thời điểm định nghĩa của foo.

+0

Biên dịch là một điều, nhưng còn yêu cầu thư viện ở phía ClojureScript thì sao? Trong ví dụ trên, có vẻ như bạn cần yêu cầu không gian tên thanh trong mô-đun ClojureScript đang gọi macro foo, có nghĩa là mô-đun gọi điện phải biết chi tiết triển khai về macro. –

+0

Một ví dụ về vấn đề tôi đã đề cập được trải nghiệm bởi thư viện Hiccups. Bạn có thể thấy giải pháp của họ ở đây, đó là loại hacky: https://github.com/teropa/hiccups#usage –

+1

Tôi nghĩ rằng đây là một vấn đề cơ bản với việc thực hiện clojurescript như nó tồn tại.Tôi gợi ý những gì tôi tin là cách tốt nhất để làm việc với nó, nhưng tôi hiểu rằng nó ít hơn lý tưởng. Nhưng về cơ bản, điều này không khác với cách sử dụng macro trong mã clojure thuần túy - macro tìm kiếm các hàm mà nó tạo ra các biểu tượng cho thời gian gọi. – noisesmith

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