Как я могу изменить список на код в макросе Clojure? - PullRequest
3 голосов
/ 07 июля 2011

У меня есть следующий макрос:

(defmacro ss [x]

`(clojureql.core/select 
      (clojureql.core/table db "users_table")
      (clojureql.core/where  ~x)
  )
)

(macroexpand '(ss '(= :type "special")))

: но он производит:

(clojureql.core/select (clojureql.core/table oe.db.dbcore/db "users_table") (clojureql.core/where '(= :type "special"))) 

: вместо:

(clojureql.core/select (clojureql.core/table oe.db.dbcore/db "users_table") (clojureql.core/where (= :type "special"))) 

: Я понимаю, что проблема в том, что я передаю список '(=: type "special"), но как я могу получить это в кавычках в макросе?

Обновление:

Я, наконец, получил эту работу благодаря ответу Микеры, сделав следующее:

(defn ss [x]

  (clojureql.core/select 
      (clojureql.core/table db "users_table")
      x
  )


)

(macroexpand '(ss (eval `(clojureql.core/where ~'(= :type "special")))))

: хотя вывод немного отличается, он работает как положено:

(ss (eval (clojure.core/seq (clojure.core/concat (clojure.core/list 'clojureql.core/where) (clojure.core/list '(= :type "special")))))) 

Ответы [ 2 ]

3 голосов
/ 07 июля 2011

Похоже, что вы передаете неправильную вещь в macroexpand: вам, вероятно, следует использовать:

(macroexpand '(ss (= :type "special")))

т.е. вам нужна только одна кавычка в начале, чтобы процитировать все выражение.

2 голосов
/ 08 июля 2011

Вы не можете передавать аргументы времени выполнения макросам, поскольку первые известны только во время выполнения, тогда как последние уже раскрываются и компилируются во время хорошо компиляции.

Вы должны использовать функцию.

(defn get-users-by-type
  [t]
  (cql/select
    (cql/table db "users_table")
    (cql/where (= :type t))))
...