2015-02-15 4 views
2

Что касается metronome функции из библиотеки Clojure Обертонной, все примеры, которые я изучил, кажется, использовать его как это: (Пример взят из https://github.com/overtone/overtone/wiki/Live-coding)Используя метроном в рекурсивной функции в Clojure/обертонов

(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 для повышения эффективности. Поэтому мой вопрос: есть ли лучший способ написать вышеприведенную функцию?

Спасибо, Найл

ответ

2

Насколько as I can see, это на самом деле не рекурсия. Вместо этого оценка функции player вызывает в качестве побочного эффекта будущую оценку функции в графике #'player. Возвращаемое значение этой оценки не зависит от следующей оценки, и каждая оценка отбрасывается из стека до следующего запуска.
Таким образом, на самом деле нет стоп-звонков, которые могли бы обрушиться на нас recur. Каждый вызов после первого происходит от одних и тех же функций планировщика. Если вы использовали recur, вы потеряли бы возможность повторно привязать переменную var к различным функциям для живого кодирования, поэтому в рамках этой функции это самый универсальный способ ее написания.

+0

Спасибо. Я очень удивился, поняв ваш ответ. – Niall