макрос макросов если-пусто? - PullRequest
2 голосов
/ 06 июня 2011

Я написал if-pred?макрос следующим образом

(defmacro if-pred?
  ([pred lst then] `(if (~pred ~lst) ~then nil))
  ([pred lst then else] `(if (~pred ~lst) ~then ~else)))

Теперь я хочу построить if-empty?макрос из этого.

(defmacro if-empty? [lst then & else] 
  (if-pred? empty? lst then else))

Я хочу использовать if-empty?как:

(if-empty? '()
       (println "empty")
       (println "not-empty"))

Но, видимо, если - пусто?не работает.Когда я запускаю приведенный выше код, not-empty выводится на печать несущественным из того, передан ли мне список if-empty?действительно пусто или нет.После печати непусто java.lang.NullPointerException выдается.

Ответы [ 4 ]

4 голосов
/ 06 июня 2011

Вы не цитируете расширение (defmacro if-empty? ...), и вы вводите необязательный аргумент else в список.

(defmacro if-empty? 
  ([lst then else] 
    `(if-pred? empty? ~lst ~then ~else))
  ([lst then] 
    `(if-pred? empty? ~lst ~then)))
0 голосов
/ 07 июня 2011

Поскольку макрос if-empty? имеет сигнатуру, отличную от if-pred? с переменной арностью остальной части, ему необходим блок do для правильной работы.

Ваш макрос if-empty? имеет несколько проблем, во-первых, он не имеет обратных кавычек, что приведет к

Так что если вам нужно, чтобы if-empty? работал так, чтобы он вычислял одно выражение, если заданная последовательность пуста, и несколько, если последовательность не пуста, должен работать следующий макрос:

(defmacro if-empty? [lst then & else] `(if-pred? empty? ~lst ~then (do ~@else)))

Если аргументы & before были несчастным случаем, должны работать следующие:

(defmacro if-empty? [lst then else] `(if-pred? empty? ~lst ~then ~else))

Как примечание, поскольку предикаты этих макросов не используются, я бы не использовал? в конце их имени.

0 голосов
/ 06 июня 2011

Это ваш if-empty? макро. Вы забыли помешать телу. Должно быть:

(defmacro if-empty? [lst then & else]
  `(if-pred? empty? ~lst ~then ~else))
0 голосов
/ 06 июня 2011

Макросам нужно возвращать код.Попробуйте это:

(defmacro if-empty? [lst then & else] 
    `(if-pred? empty? ~lst ~then ~@else))
...