Сейчас я изучаю 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, вместо того, чтобы искать какое-то время, прежде чем наткнуться на него.