Подтвердить что ты не робот

Выполнение нескольких операторов в if-else без исключения nullpointer

Я пытаюсь углубиться в clojure и функциональное программирование.

В какой-то момент моего кода у меня есть (def server (spawn-server)). Теперь я хочу короткую функцию для REPL, чтобы проверить состояние этого сокета.

Это то, что у меня есть на данный момент:

(defn status []
  (if server 
    (
      (println "server is up and running")
      (println "connections:" (connection-count server)) 
     )    
    (println "server is down")))

Если сервер равен нулю, все работает нормально, но это результат на REPL, если сервер работает:

=> (status)
server is up and running
connections: 0
#<CompilerException java.lang.NullPointerException (NO_SOURCE_FILE:0)>

Я не уверен, вижу ли я проблему, но я не могу понять, как это должно работать:-) Что у меня здесь есть:

((println "foo")(println "foo"))

который будет оцениваться как (nil nil), что приводит к исключению NullPointerException?

Обычно я бы не использовал внешние скобки, но как я могу создать какой-то оператор "block" для if-condition. Если я их не использую, второй println будет использоваться как еще.

Будет работать использование let как своего рода "block" -statement:

(let [] 
  (println "server is up and running"),
  (println "connections:" (connection-count server)) )

Но я не уверен, правильно ли это решение?

4b9b3361

Ответ 1

Используйте do:

(defn status []
  (if server 
    (do
      (println "server is up and running")
      (println "connections:" (connection-count server)))    
    (println "server is down")))

В Lisps, как правило, вы не можете просто добавлять parens для группировки.

((println "foo") (println "foo"))

Здесь возвращаемое значение первого (println "foo") будет пытаться вызываться (как функция), а возвращаемое значение второго в качестве аргумента. Это очень простые правила оценки, поэтому я предлагаю вам попасть в некоторые вводные книги или документацию о Clojure или Lisps в целом.

В разделе evaluation Clojure homepage:

Непустые списки считаются вызовами либо специальным формам, либо макросам, либо функции. Вызов имеет форму (операнды оператора *).

Макросы или специальные формы могут "нарушить" это правило.