Как обновить атом из нескольких будущих (ей) в Clojure? - PullRequest
0 голосов
/ 26 марта 2020

Я пытался выполнить следующее упражнение из Brave Clojure book:

Создать функцию, которая использует фьючерсы для распараллеливания задачи загрузки случайных цитат из http://www.braveclojure.com/random-quote с использованием (slurp "http://www.braveclojure.com/random-quote"). Фьючерс должен обновить атом, который ссылается на общее количество слов для всех кавычек. Функция примет количество кавычек для загрузки в качестве аргумента и вернет конечное значение атома. Имейте в виду, что вам нужно убедиться, что все фьючерсы завершены, прежде чем возвращать конечное значение атома.

Это мое решение:

(def i (atom {}))
(defn update-vals [map vals f]
(reduce #(update-in % [%2] f) map vals))
(defn incifnil [x] (if (nil? x) 1 (inc x)))
(require '[clojure.string :as str])
(defn splitwords [s] (str/split s #"\W"))
(defn word-counting [map s] (update-vals map (splitwords s) incifnil))
(defn update-i [s] (swap! i word-counting s))
(defn bring-quote [] (slurp "https://www.braveclojure.com/random-quote"))
(defn future-creator [] (future (update-i (bring-quote))))
(defn list_of_futures [n] (map (fn [_] (future-creator)) (range n)))
(defn checkall-futures [future-list] (map deref future-list))
(defn quote-word-count [n] (do
                            (checkall-futures (list_of_futures n))
                            @i))

Но если я попытаюсь взять последнее значение atom i из REPL Я беру пустую карту. Что я делаю не так?

Ответы [ 2 ]

3 голосов
/ 26 марта 2020

map у вас checkall-futures ленивый. Вам нужно что-то, что заставляет deref на всех предметах. Например, используйте run! вместо map там.

0 голосов
/ 26 марта 2020

Помимо использования run!, еще одним удобным трюком является использование mapv вместо map везде. mapv всегда дает векторный результат и не ленив. Это устраняет многие проблемы, связанные с ленивостью / синхронизацией при отладке, особенно в REPL.

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

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