Запустите две команды в строке после инструкции if в Clojure

Почему следующая программа Clojure запускает исключение NullPointerException?

user=> (defn x []  
       "Do two things if the expression is true."
       (if true ((println "first expr") (println "second expr")) false))

user=> (x)
first expr
java.lang.NullPointerException (NO_SOURCE_FILE:0)
second expr

Это упрощенная версия моего фактического варианта использования, где я хочу выполнить, возможно, три оператора (вытащить значения из БД), прежде чем возвращать карту - {:status 200, :body "Hello World"} внутри ветки.

Ответы

Ответ 1

Он пытается обработать результат первого println как функцию вызова второй функции println.

Вам нужен do.

(defn x []  
   "Do two things if the expression is true."
   (if true (do (println "first expr") (println "second expr")) false))

(x)

Специальная форма do (progn в CL, начинающаяся с Scheme) последовательно выполняет каждый из своих аргументов и возвращает результат последней.

Ответ 2

Если nil нормально как возвращаемое значение в случае else, рассмотрите использование when, у которого есть неявный блок do:

(defn x []  
  "Do two things if the expression is true."
  (when true
    (println "first expr") 
    (println "second expr")))

Ответ 3

Не важно, что это имеет значение в вашем конкретном случае, но знаете разницу между (do ...), которая будет загружать каждую форму в свой собственный загрузчик классов, и пустую форму let (let [] ...), которая оценивает всю форму в одном загрузчике классов.