Использование метронома в рекурсивной функции в 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 к различным функциям для живого кодирования, поэтому в среде кажется, что это самый универсальный способ его написания.

Другие вопросы по тегам