Использование метронома в рекурсивной функции в clojure/overtone
Учитывая metronome
функция из библиотеки Clojure Overtone, все примеры, которые я изучал, используют ее следующим образом: (пример взят из https://github.com/overtone/overtone/wiki/Live-coding)
(defn player [beat]
(at (metro beat) (kick))
(at (metro (+ 0.5 beat)) (c-hat))
(apply-by (metro (inc beat)) #'player (inc beat) []))
(player (metro))
(для контекста: metro является экземпляром метронома; звучит звук удара и c-hat) Как вы можете видеть, рекурсия обрабатывается самой вызывающей функцией. Помимо статей об обертоне, большинство других статей Clojure рекомендуют использовать этот тип рекурсии и рекомендуют использовать функцию recur для повышения эффективности. Итак, мой вопрос: есть ли лучший способ написания вышеуказанной функции?
Спасибо Найл
1 ответ
Насколько я понимаю, это не совсем рекурсия. Вместо этого, оценка player
функция вызывает, как побочный эффект, будущую оценку функции в #'player
вар планируется. Возвращаемое значение этой оценки не зависит от следующей оценки, и каждая оценка отсоединяется от стека до начала следующей.
Так что на самом деле там нет стека самовывозов, которые recur
может рухнуть для нас. Каждый вызов после первого происходит из одних и тех же функций планировщика. Если вы использовали recur
тогда вы потеряете возможность повторно привязывать var к различным функциям для живого кодирования, поэтому в среде кажется, что это самый универсальный способ его написания.