Common Lisp tiene return-from
; ¿Hay algún tipo de return
en Clojure para cuando quiere regresar temprano de una función?¿Cómo regresas de una función temprano en Clojure?
Respuesta
No hay ninguna declaración de devolución explícita en clojure. Podrías hackear algo juntos usando una combinación catch/throw si lo deseas, pero como clojure es mucho más funcional que el ceceo común, las posibilidades de que necesites un retorno temprano justo en el medio de un bloque anidado son mucho más pequeñas que en CL. La única 'buena' razón que puedo ver para declaraciones de devolución es cuando se trata de objetos mutables de una manera que no es idiomática en clojure.
No llegaría tan lejos como para decir que nunca es útil, pero creo que en Clojure, si su algoritmo necesita una declaración de devolución, es un gran olor a código.
Gracias por la sugerencia. Como un ejemplo concreto: al analizar args de línea de comando, quería verificar si cada opción era válida. Al principio, traté de verificar cada opción, si una opción no era válida, entonces quería devolver un mensaje útil al usuario antes de continuar validando el resto de las opciones. Después de realizar el retorno en medio de la función es un olor a código, escribí una función "validar" que devuelve una lista de mensajes (un mensaje por cada valor de opción no válido). Si la lista de mensajes devueltos por validate está vacía, entonces todas las opciones se validaron correctamente. ¡Mucho mejor después del refactor! – Upgradingdave
En resumen, no. Si esto es un verdadero problema para usted, entonces usted puede conseguir alrededor de él con "the maybe monad" mónadas tienen una alta sobrecarga intelectual por lo que para muchos casos clojurians tienden a evitar el estilo "si el retorno fallido" de la programación.
Ayuda a dividir la función en funciones más pequeñas para reducir la fricción.
No soy un experto en Clojure, pero parece que no tiene esas construcciones para intentar ser más funcional. Echar un vistazo a lo que Stuart Halloway dice here:
Common Lisp también es compatible con un retorno de lo macro a "retorno" de la medio de una función. Esto fomenta un estilo imperativo de la programación , que Clojure desalienta.
Sin embargo, puede resolver los mismos problemas de otra manera. Aquí es el retorno de ejemplo, reescrito en un estilo funcional para que no -de retorno es necesaria:
(defn pair-with-product-greater-than [n]
(take 1 (for [i (range 10) j (range 10) :when (> (* i j) n)] [i j])))
Es decir, utilizar secuencias perezosos y los valores que vuelven sobre la base de condiciones.
A menos que esté escribiendo un código realmente funky, la única razón por la que querrá volver temprano es si se cumple alguna condición. Pero como las funciones siempre devuelven el resultado de la última forma evaluada, if
ya es esta función; simplemente coloque el valor que desea devolver en el cuerpo del if
y devolverá ese valor si se cumple la condición.
El if
opción ya dada es probablemente la mejor opción, y la nota ya que los mapas son fáciles, usted siempre puede volver {:error "blah"}
en la condición de error, y {result: x}
en la condición válida.
No hay una declaración de devolución en Clojure. Incluso si elige no ejecutar algún código utilizando una construcción de flujo como if
o when
, la función siempre devolverá algo, en estos casos nil
. La única salida es arrojar una excepción, pero incluso así, o bien burbujeará completamente y matará a su hilo, o se verá atrapado por una función, que devolverá un valor.
Cuando necesite salir temprano de un cálculo, necesita una forma de hacerlo, no un argumento de los puristas.Por lo general, lo necesita cuando está reduciendo una gran colección y un cierto valor indica que no tiene sentido seguir procesando la colección. Con ese fin, el siempre práctico Clojure proporciona la función reduced
.
Un ejemplo simple para ilustrar es que al multiplicar una secuencia de números, si encuentra un cero, ya sabe que el resultado final será cero, por lo que no necesita mirar el resto de la secuencia. He aquí cómo usted código que con reduced
:
(defn product [nums]
(reduce #(if (zero? %2)
(reduced 0.0)
(* %1 %2))
1.0
nums))
reduced
envuelve el valor que le dan en una estructura de datos centinela para que reduce
sabe que dejar de leer desde la recogida y devuelva el valor reduced
en este momento. ¡Oye, es puramente funcional, incluso!
Se puede ver lo que está pasando, si se coloca la anterior if
en un do
con un (println %1 %2)
:
user=> (product [21.0 22.0 0.0 23.0 24.0 25.0 26.0])
1.0 21.0
21.0 22.0
462.0 0.0
0.0
user=> (product [21.0 22.0 23.0 24.0 25.0 26.0])
1.0 21.0
21.0 22.0
462.0 23.0
10626.0 24.0
255024.0 25.0
6375600.0 26.0
1.657656E8
Esta debería ser la respuesta correcta. "Cuando necesitas salir temprano de un cálculo, necesitas una forma de hacerlo, no un argumento de los puristas". La eficiencia es siempre una necesidad. Período. Ejemplo de una función para verificar si una identificación está duplicada en un conjunto de mapas: (defn duplicado? [Id myset] (reduce (fn [av] (if (= (: id v) id) (reducido verdadero) falso)) falso myset)) – Chocksmith
- 1. ¿Mejor método de Java Sintaxis? ¿Regresas temprano o tarde?
- 2. Regreso temprano de una función en el ASP clásico
- 3. Cómo regresas de 'gf' en Vim
- 4. ¿Cómo puedo definir una función en Clojure?
- 5. Cómo "escapar temprano" en una mónada web
- 6. Cómo defnir una función de una cadena en Clojure?
- 7. una función de Fibonacci recursiva en Clojure
- 8. ¿Cómo convertir una cadena a una función en Clojure?
- 9. Clojure: Cómo crear una función en tiempo de ejecución
- 10. Ejecutando una función enlazada dinámicamente en Clojure
- 11. ¿Cómo implementar lambda como una función llamada "lambda" en Clojure?
- 12. cómo devolver una función clojure como una cadena
- 13. Clojure: determine si existe una función
- 14. Tratar macro Clojure como una función
- 15. Cómo llamar a una función variadica de Clojure desde Java
- 16. ¿Cómo encuentro dinámicamente metadatos para una función de Clojure?
- 17. NSURLConnection cierra temprano en GET
- 18. Clojure Función Literales
- 19. ¿Cómo usar la función doc de clojure?
- 20. ¿Regresar temprano de una función es más elegante que una instrucción if?
- 21. Alinear una función con macros Clojure
- 22. Limpiar la función Clojure
- 23. rareza en función de mapa clojure
- 24. Llamar a una función desde una cadena con el nombre de la función en Clojure
- 25. ¿Cómo puedo examinar el bytecode JVM para una función clojure?
- 26. Función de estilo Clojure "subprocesamiento" en Python
- 27. ¿Cómo puedo definir una función dentro de una función en Clojure y hacer referencia a esa función?
- 28. Función de modo idiomático en Clojure
- 29. WPF UIElement.IsHitTestVisible = false; ¿Aún regresas éxitos?
- 30. ¿Cómo detener el procesamiento de un JSP temprano?
código Clojure tiende a no ser estructurado como una serie de declaraciones, por lo que regresar temprano no es necesariamente tan significativa . Si desea dar un ejemplo de dónde lo desea, las personas podrían sugerir alternativas. – Chuck