2011-06-04 15 views
39

Estoy tratando de cavar un poco más profundo en clojure y la programación funcional.ejecutar varias declaraciones en si-persona sin excepción NullPointer

En algún momento de mi código que tienen un (def server (spawn-server)). Ahora quiero una breve función de REPL para verificar el estado de este socket.

Esto es lo que tengo en este momento:

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

Si el servidor es nulo, todo funciona bien, pero esta es la salida en el REPL si el servidor está en ejecución:

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

No estoy seguro si veo el problema, pero no puedo entender cómo debería funcionar esto :-) Lo que tengo aquí es esto:

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

que se evaluará a (nil nil) que da como resultado la NullPointerException?

Usualmente no usaría el paréntesis externo, pero ¿cómo puedo crear algún tipo de instrucción de "bloque" para la condición if? Si no los uso, la segunda impresión se usará como otra cosa.

lo que funcionaría es el uso de Let como una especie de -statement "bloque":

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

pero no estoy muy seguro de si esto la solución "correcta"?

Respuesta

53

Uso do:

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

En Lisp, por lo general, no se puede simplemente añadir parens para la agrupación.

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

En este caso, el valor de retorno de la primera (println "foo") serán juzgados a ser llamado (en función), con el valor de retorno de la segunda como un argumento. Esas son reglas de evaluación muy básicas, por lo que le sugiero que acceda a algunos libros introductorios o documentación sobre Clojure o Lisps en general.

Desde la sección evaluation del Clojure homepage:

Non-empty Lists are considered calls to either special forms, macros, or functions. A call has the form (operator operands*).

macros o formas especiales pueden "romper" esta regla.

+0

Gracias, eso fue lo que busqué. – echox

+0

¿Por qué la excepción del puntero nulo después de todos estos años? esto es tan antipático ;-) – matanster

+1

@matanster No sé mucho sobre las razones, pero estoy de acuerdo con que los mensajes de error de Clojure no son los mejores. – danlei

Cuestiones relacionadas