Escuché a alguien decir que su idioma tiene una convención donde los nombres de las funciones que mutan el estado deben terminar con un signo de exclamación. Estoy tratando de escribir un código más funcional y me gusta la idea de marcar de alguna manera las funciones de acuerdo con su estado de efectos secundarios, es decir, ninguno, efectos secundarios internos, efectos secundarios externos (desconozco la terminología de fp correcta, pero se entiende la idea I esperanza).
Obviamente, es fácil para mí idear mi propio esquema de nombres, pero me preguntaba si tales esquemas / convenciones ya existen antes de irme a casa.
editar: Gracias por todas las respuestas, eso fue exactamente lo que estaba buscando y las encontré todas realmente útiles. Probablemente debería haber mencionado que estoy refactorizando algunos JavaScript antiguos, por lo que, si bien los lenguajes estáticamente escritos pueden imponer una diferencia entre el código con y sin efectos secundarios, tendré que confiar en una convención de nomenclatura autoimpuesta.
edit2: En cuanto a los mods que cierran esto como principalmente basado en opiniones, tengo que estar en desacuerdo. Me preguntaba qué convenciones eran de uso común, si es que existían, ¡esta es, por definición, una cuestión de hecho, no de opinión!
fuente
!
(no sería sintácticamente válido mutar el estado de una variable sin ese operador, si la memoria sirve ), por lo que en realidad es una convención bastante sensata en ese idioma .set!
para mutar una variable, pero no un!
operador independiente . La convención existe porque Lisp tiene un historial de uso de símbolos en identificadores para transmitir significado debido a muy pocas restricciones sobre qué es un identificador válido. La falta de restricciones existe debido al enfoque de Lisp en macros y lenguajes específicos de dominio.!
convención (por ejemplo, fordowncase
anddowncase!
), pero indica "peligro" más generalmente que "efectos secundarios".Respuestas:
Siga la separación de comando-consulta . Las funciones que devuelven valores no tienen efectos secundarios, las funciones que tienen efectos secundarios no devuelven valores.
También ayuda nombrar funciones que devuelven valores después de lo que devuelven, es decir, un sustantivo o adjetivo. Mientras que las funciones que tienen efectos secundarios deben nombrarse después del efecto que realizan, es decir, un verbo.
Entonces, por ejemplo,
myArray.sort()
tiene un efecto secundario, ordena la matriz. Por lo tanto, no devuelve nada y lleva el nombre de un verbo. Mientras tanto,myArray.sorted()
devuelve una copia ordenada demyArray
. Por lo tanto, no tiene ningún efecto secundario y lleva el nombre de lo que devuelve.Para su información, la idea anterior (sustantivos / adjetivos para funciones puras y verbos para funciones productoras de efectos secundarios) es un estándar en Swift 3.
( https://swift.org/documentation/api-design-guidelines/#strive-for-fluent-usage )
fuente
El problema fundamental es que los efectos secundarios no se capturan en el sistema de tipos. El uso de una convención de nomenclatura de funciones es un mal sustituto de la verificación estática. Hay algunas formas de evitar esto.
Haskell usa mónadas para capturar efectos secundarios dentro de un contexto. La
bind
operación monádica compone funciones impuras tanto como el operador de composición de funciones normales compone funciones puras. Las leyes de mónada aseguran que este operador actúe de manera análoga a la composición regular.Otra ruta es la de separar puro a partir impuro mediante la separación de las expresiones de los comandos del todo . Estas son dos categorías sintácticas completamente diferentes que no se pueden mezclar. Las expresiones tienen tipos que nos permiten componer términos. Una expresión, por definición, no puede depender de ningún asignable (no tiene acceso a la tienda ). Los comandos no tienen un tipo en el sentido tradicional y no pueden devolver un valor. Solo pueden interactuar con el programa mutando la tienda.
Tenga en cuenta que los lenguajes "funcionales" convencionalmente seguros de escribir pueden no seguir ninguno de estos paradigmas. Por ejemplo, OCaml y SML no diferencian adecuadamente las funciones puras de las impuras.
Ninguna de estas soluciones es perfecta, y esta sigue siendo un área activa de investigación.
fuente
Llamar a métodos o funciones parece una idea fantástica porque podría ayudar a eliminar los momentos en que el código introduce un nivel de inseguridad. Joel Spolsky profundiza bastante en esta idea en su artículo Cómo hacer que el código incorrecto parezca incorrecto ( http://www.joelonsoftware.com/articles/Wrong.html ) donde recomienda utilizar una versión menos conocida de la notación húngara para hacer ciertas ideas más transparentes dentro del sistema.
El lenguaje al que se refiere es casi seguro el Esquema (consulte http://download.plt-scheme.org/doc/html/guide/set_.html para ver un ejemplo sencillo). No estoy al tanto de nada global.
Los prefijos de Java métodos de propiedad con
get
yset
para cumplir parcialmente este propósito, pero no estoy al tanto de ninguna convención común del tipo que mencionas fuera del mundo de Lisp que no están (como señaló @gardenhead) incrustadas en el sistema de tipos.Creo que, en general, es bastante seguro crear una pauta de estilo para su equipo, particularmente si se trata de algo con mucha concurrencia donde los efectos secundarios son aún más peligrosos de lo habitual.
Para lo que sea que valga, puedo pensar en un par de formas de implementar esto en lenguajes ALGOL-esque. Uno simple podría ser un prefijo, como lo sugirió cuasi Spolsky, digamos
s_
para operaciones con estado yl_
para operaciones sin estado.Una idea más moderna podría ser poner palabras como prefijos o sufijos. Quizás
calculate
es una función pura peromutateCalculation
es la impura.Finalmente, hay un grado en el que mucho de esto debería manejarse separando las preocupaciones; solo la capa que actualiza la base de datos debería ser capaz de actualizar la base de datos, por ejemplo. En ese caso, es bastante obvio que debe preocuparse por los efectos secundarios en las capas con estado.
fuente