#clojure
#clojure
Вопрос:
Есть ли в Clojure макрос считывателя или основная функция, которая похожа на recur
, но возможна с положением без хвоста?
Например, в этой рекурсивной функции
(defn insertR* [newkey oldkey l]
(cond
(empty? l) '()
(not (seq? (first l)))
(if (= (first l) oldkey)
(cons oldkey (cons newkey (insertR* newkey oldkey (rest l))))
(cons (first l) (insertR* newkey oldkey (rest l))))
:else
(cons (insertR* newkey oldkey (first l)) (insertR* newkey oldkey (rest l)))))
Есть ли какая-нибудь универсальная функция, которую я могу использовать для вызова самой себя вместо insertR*
явного вызова?
Ответ №1:
Ваш вопрос неясен. Если вы имеете в виду: могу ли я сделать это без использования пространства стека? Нет. У вашего insertR*
есть несколько самостоятельных вызовов, и это невозможно выразить без стека.
Если вы имеете в виду: могу ли я использовать слово типа recur
для обозначения «Вызывайте себя рекурсивно», и мне все равно, использует ли оно stack? Не совсем. Впрочем, вы могли бы написать ее самостоятельно. Что-то вроде:
(defmacro defrec [name amp; fntail]
`(def ~name (fn ~'recurse ~@fntail)))
(defrec foo [x]
(when-not (zero? x)
(recurse (dec x))))
Я подозреваю, что в этом есть несколько пробелов, но в основном это делает то, о чем вы думаете.
Ответ №2:
Зачем вам такая функция / макрос? recur создан для оптимизации конечных вызовов. Кажется, что ваша функция этого не допускает (возможно, я ошибаюсь). Хотя вы сказали, что вам это не нужно. Почему вы хотите явно заменить ваш вызывающий insertR * на что-то другое? Если вам не нравится каждый раз передавать newkey oldkey (а они не изменены), вы можете создать внутреннюю функцию, которая будет использовать эти ключи.
Комментарии:
1. Просто чтобы я мог выделить рекурсивные вызовы в моей IDE с использованием универсального ключевого слова