Clojure: когда использовать memoize, а когда использовать delay / force? - PullRequest
0 голосов
/ 19 марта 2020

Я только начал изучать Clojure и пытался понять разницу между двумя подходами, которые на первый взгляд кажутся очень идентичными.

(def func0 (delay (do 
                    (println "did some work") 
                    100)))
so.core=> (force my-delay2)
did some work
100
so.core=> (force my-delay2)
100
(defn vanilla-func [] (println "did some work") 100)
(def func1 (memoize vanilla-func))
so.core=> (func1)
did some work
100
so.core=> (func1)
100

Оба подхода выполняют своего рода запоминание функций. Чего мне не хватает?

Я пытался найти объяснение по https://clojuredocs.org/clojure.core/delay & https://clojuredocs.org/clojure.core/memoize, но не смог.

1 Ответ

5 голосов
/ 19 марта 2020

delay содержит один результат, и вам нужно deref, чтобы получить результат. memoize - это несвязанный кеш, который кэширует результат в зависимости от входных аргументов . Например,

user=> (def myinc (memoize (fn [x] (println x) (inc x))))
#'user/myinc
user=> (myinc 1)
1
2
user=> (myinc 1)
2

В вашем примере (без аргументов) единственное отличие состоит в том, что вы можете использовать результат напрямую (без deref необходимости)

Classi c сценарии использования для delay - это вещи, которые понадобятся позже, что приведет к блокировке или задержке запуска. Или, если вы хотите «скрыть» верхний уровень def s от компилятора (например, они вызывают побочные эффекты).

memoize - это кэш classi c, который лучше всего использовать, если расчет это дорого, и набор входных аргументов не является чрезмерным. Есть и другие варианты кэширования в стихе clojure, которые позволяют лучше конфигурировать (например, они не связаны).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...