Я пытаюсь написать функцию, которая возвращает запомненную рекурсивную функцию в Clojure, но мне не удается заставить рекурсивную функцию видеть свои собственные запомненные привязки. Это потому, что там нет созданного var? Кроме того, почему я не могу использовать memoize для локальной привязки, созданной с помощью let?
Этот немного необычный создатель последовательности Фибоначчи, который начинается с определенного числа, является примером того, что я хотел бы сделать:
(defn make-fibo [y]
(memoize (fn fib [x] (if (< x 2)
y
(+ (fib (- x 1))
(fib (- x 2)))))))
(let [f (make-fibo 1)]
(f 35)) ;; SLOW, not actually memoized
Использование with-local-vars
кажется правильным подходом, но он также не работает для меня. Я полагаю, я не могу закрыть переменную?
(defn make-fibo [y]
(with-local-vars [fib (fn [x] (if (< x 2)
y
(+ (@fib (- x 1))
(@fib (- x 2)))))]
(memoize fib)))
(let [f (make-fibo 1)]
(f 35)) ;; Var null/null is unbound!?!
Конечно, я мог бы вручную написать макрос, который создает замкнутый атом, и самостоятельно управлять мемоизацией, но я надеялся сделать это без такой хакерской атаки.