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

Вчера я играл в Clojure, реализуя базовый бинарный поиск. После написания алгоритма я дал ему несколько прогонов в REPL. Это работало безотказно. Затем я написал код для проверки своей реализации в функции точки входа -main. Но странно, что это не сработало.

Я попытался напечатать несколько вещей внутри -main перед вызовом моего алгоритма бинарного поиска, и он напечатал. Но все равно мой алгоритм не вызывался. Мой код выглядел примерно так:

(defn -main
    [& args]
  (map (fn [to-find] (println (binary-search/search data-array to-find))))

Но хотя тот же map работал в функции REPL, он ничего не делал внутри функции -main. После того, как я некоторое время ломал голову, несколько поисковых запросов в Google указали мне правильное направление.

Я забыл, что map возвращает ленивый список. Он не оценивается до тех пор, пока не понадобится. Внутри REPL были оценены все значения, поэтому мой код работал там. В функции -main, поскольку нечего было оценивать map, я не получал результатов.

Исправить это просто, используйте dorun следующим образом:

(defn -main
    [& args]
  (dorun (map (fn [to-find] (println (binary-search/search data-array to-find)))))

Как говорится в этом ответе StackOverflow, вы также можете использовать doseq для достижения того же эффекта, хотя у него немного другой синтаксис.

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