ЦеНеБлог

(Лінь [])

« Знов про суржикофобію | | Розкладки: оновлення »

17 липня 2012

(Лінь [])

Написав невеличкий макрос, що дозволяє створювати ліниві послідовності в стилі loop-recur.

    
(defmacro lazy-loop [params & body]
(let [[args argvals] (->> params (partition 2) (apply map list))] `(letfn [(~'lazy-recur [~@args] (lazy-seq ~@body))] (~'lazy-recur ~@argvals))))

Приклад використання:

user=> (lazy-loop [a 5] 
(if (> a 0)
(cons a
(lazy-recur (dec a))))) (5 4 3 2 1)
user=> (lazy-loop [i (range)
m [0 0 1 1 0 1 0 1]]
(if (seq m)
(if (= (first m) 0)
(lazy-recur (rest i) (rest m))
(cons (first i)
(lazy-recur (rest i) (rest m)))))) (2 3 5 7)

lazy-recur — просто ім'я функції для рекурсивного виклику; вимог щодо хвостової позиції нема, але (оскільки результатом lazy-loop має бути або послідовність, або nil) доречно розміщувати його останнім елементом у cons чи concat, що повертається як результат, або в хвостовій позиції.

Автор: Python. Опубліковано 17 липня 2012 12:40
Змінено 17 липня 2012 12:46
Категорії: Clojure, Програмерство