Я не понимаю всей вашей цели: многие термины, которые вы используете, расплывчаты. Например, что вы хотите сказать, что хотите оценить последовательность функций, а затем повторить их результаты? Эти функции должны быть функциями без аргументов (thunks), тогда, я полагаю? Но наличие thunk, который сначала возвращает x, а затем возвращает y в следующий раз, когда вы его вызываете, довольно мерзок и полон состояния. Возможно, батут решит часть вашей проблемы?
Вы также ссылались на то, чего хотите избежать, но, похоже, вставили не ту ссылку - это всего лишь ссылка на эту страницу. Если вы хотите избежать переполнения стека, то батут, вероятно, будет хорошим способом справиться с этим, хотя это должно быть возможно только с помощью loop / recur. Это понятие о том, что thunks возвращают x, если они не возвращают y, равно madness , если ваша главная цель - избежать переполнения стека. Не делай этого.
Я пошел дальше и угадал наиболее вероятную конечную цель, которую вы могли бы достичь, и вот моя реализация:
(defn call-until-number [& fs]
(let [numeric (fn [x] (when (number? x) x))]
(loop [fs fs]
(let [result (map #(%) fs)]
(or (some numeric result)
(recur result))))))
(call-until-number (fn [] (fn [] 1))) ; yields 1
(call-until-number (fn [] (fn [] 1)) ; yields 2
(fn [] 2))
(call-until-number (fn f [] f)) ; never returns, no overflow