В clojure, как написать defn-подобный макрос, где функция завершится при первом сбое? - PullRequest
0 голосов
/ 26 февраля 2012

В ближайшем будущем я хотел бы написать макрос defn-my, который создает функцию с body. И когда эта функция выполняется, она выходит из первого оператора, который не возвращает 0.

Например:

(defn f1[] (println "f1") 5)
(defn f2[] (println "f2") 0)
(defn-my foo[] (f1) (f2))     
(defn-my bar[] (f2) (f1))
(foo); should execute f1 and exit
(bar); should execute f2 and then f1

Ответы [ 2 ]

4 голосов
/ 26 февраля 2012

Я думаю, вы просите что-то вроде этого:

(defmacro and-zero
  ([] true)
  ([x] (zero? x))
  ([x & next] 
    `(let [and# (zero? ~x)]
       (if and# 
         (and-not-zero ~@next)
         and#))))

user=> (and-zero 0 0 0)
true
user=> (and-zero 0 1 0)
false

Макрос предполагает, что каждое выражение оценивается как число.Он выдаст исключение, если, например, выражение оценивается как nil.

. Тогда вы можете написать yout defn-my, например:

(defmacro defn-my [ & body ] `(and-zero ~@body))
1 голос
/ 26 февраля 2012

Просто используйте поведение короткого замыкания and:

(defn foo []
  (and (f1) (f2)))

(defn bar []
  (and (f2) (f1)))

Результаты:

user=> (foo)
f1
nil
user=> (bar)
f2
f1
nil

Вы можете получить противоположное поведение, оканчивающееся на первый не ноль, сor.

...