Почему рекурсивная функция не запоминается

#clojure

#clojure

Вопрос:

Привет, я не могу разобраться в этой проблеме:

 (defn integrate
  "Finding the definite integral from 0 to stop"
  ([f dx]
   (let [itg (memoize
              (fn [itg stop n]
                (if (<= n 0)
                  0
                  (  (let [b (* n dx) a (- b dx)]
                       (println "[DEBUG] stop = " stop " and n =" n) 
                       (* (- b a) (/ (  (f a) (f b)) 2))
                      )
                     (itg itg stop (dec n))))))
         itg (partial itg itg)]
     (fn [x] (itg x (quot x dx))))))

(time ((integrate (fn [x] (* x x)) 0.1) 5))
(time ((integrate (fn [x] (* x x)) 0.1) 5))
  

Я ожидаю, что во второй раз, когда я вызываю эту функцию, она должна получить запоминаемый результат, но она просто пересчитывает весь интеграл во второй раз и снова печатает отладочные сообщения.

Почему это происходит? Как это исправить?

Ответ №1:

Две проблемы. 1) Каждый вызов integrate создает новую запоминаемую функцию, поэтому второй вызов integrate не будет повторно использовать какие-либо результаты, вычисленные первым вызовом. 2) Один из параметров запоминаемой функции сам по себе является функцией. Это неправда (= (fn []) (fn [])) , поэтому памятка может совпадать не так часто, как вы надеетесь.

Ответ №2:

Вы можете найти хорошую статью по этому вопросу здесь: https://quanttype.net/posts/2020-09-20-local-memoized-recursive-functions.html