Para responder a esta pregunta, supongamos que el costo de la ambigüedad en la mente de un programador es mucho más costoso que unas pocas pulsaciones de teclas adicionales.
Dado eso, ¿por qué permitiría que mis compañeros de equipo se salgan sin anotar sus parámetros de función? Tome el siguiente código como ejemplo de lo que podría ser un código mucho más complejo:
let foo x y = x + y
Ahora, un examen rápido de la información sobre herramientas le mostrará que F # ha determinado que usted quiere que x e y sean ints. Si eso es lo que pretendías, entonces todo está bien. Pero yo no sé si eso es lo que pretende. ¿Qué pasaría si hubiera creado este código para concatenar dos cadenas juntas? ¿O qué pasa si creo que probablemente quisiste agregar dobles? ¿O qué pasa si simplemente no quiero tener que pasar el mouse sobre cada parámetro de función para determinar su tipo?
Ahora tome esto como un ejemplo:
let foo x y = "result: " + x + y
F # ahora supone que probablemente haya tenido la intención de concatenar cadenas, por lo que x e y se definen como cadenas. Sin embargo, como el pobre imbécil que mantiene su código, podría mirar esto y preguntarme si tal vez tenía la intención de agregar x e y (ints) y luego agregar el resultado a una cadena para fines de UI.
Ciertamente, para ejemplos tan simples, uno podría dejarlo ir, pero ¿por qué no aplicar una política de anotación de tipo explícito?
let foo (x:string) (y:string) = "result: " + x + y
¿Qué daño hay en ser inequívoco? Claro, un programador podría elegir los tipos incorrectos para lo que está tratando de hacer, pero al menos sé que lo intentaron, que no era solo un descuido.
Esta es una pregunta seria ... Todavía soy muy nuevo en F # y estoy abriendo el camino para mi compañía. Los estándares que adopte probablemente serán la base para toda la futura codificación F #, incrustada en el interminable pegado de copias que estoy seguro impregnará la cultura en los años venideros.
Entonces ... ¿hay algo especial en la inferencia de tipos de F # que lo convierte en una característica valiosa para mantener, anotando solo cuando sea necesario? ¿O los expertos F # -ers tienen la costumbre de anotar sus parámetros para aplicaciones no triviales?
fuente
Respuestas:
No uso F #, pero en Haskell se considera buena forma de anotar (al menos) definiciones de nivel superior, y a veces definiciones locales, a pesar de que el lenguaje tiene una inferencia de tipo generalizada. Esto es por algunas razones:
Lectura
Cuando desee saber cómo usar una función, es increíblemente útil tener disponible la firma de tipo. Simplemente puede leerlo, en lugar de tratar de inferirlo usted mismo o confiar en las herramientas para hacerlo por usted.
Refactorización
Cuando desee alterar una función, tener una firma explícita le garantiza que sus transformaciones conservan la intención del código original. En un lenguaje de tipo inferido, es posible que el código altamente polimórfico teclee pero no haga lo que pretendías. La firma de tipo es una "barrera" que concreta la información de tipo en una interfaz.
Rendimiento
En Haskell, el tipo inferido de una función puede sobrecargarse (por medio de las clases de tipos), lo que puede implicar un despacho en tiempo de ejecución. Para los tipos numéricos, el tipo predeterminado es un entero de precisión arbitraria. Si no necesita la generalidad completa de estas características, puede mejorar el rendimiento especializando la función al tipo específico que necesita.
Para las definiciones locales, las
let
variables enlazadas y los parámetros formales para lambdas, encuentro que las firmas de tipo generalmente cuestan más en código que el valor que agregarían. Entonces, en la revisión del código, sugeriría que insista en las firmas para las definiciones de nivel superior y simplemente pida anotaciones juiciosas en otro lugar.fuente
.mli
archivo de interfaz ( ) (si escribe una, lo cual se recomienda encarecidamente. Las anotaciones de tipo tienden a omitirse de las definiciones porque serían redundantes con la interfaz..fsi
archivos de firma F # ( ), con una advertencia: F # no usa archivos de firma para la inferencia de tipos, por lo que si algo en la implementación es ambiguo, aún tendrá que anotarlo nuevamente. books.google.ca/…Jon dio una respuesta razonable que no repetiré aquí. Sin embargo, le mostraré una opción que podría satisfacer sus necesidades y en el proceso verá un tipo diferente de respuesta que no sea sí / no.
Últimamente he estado trabajando con el análisis sintáctico utilizando combinadores de analizador sintáctico. Si conoce el análisis, sabe que normalmente usa un lexer en la primera fase y un analizador en la segunda fase. El lexer convierte el texto en tokens y el analizador convierte los tokens en un AST. Ahora que F # es un lenguaje funcional y los combinadores están diseñados para combinarse, los combinadores de analizador están diseñados para utilizar las mismas funciones tanto en el lexer como en el analizador, pero si configura el tipo para las funciones del combinador de analizador, solo puede usarlos para lex o analizar y no ambos.
Por ejemplo:
o
Como el código es copyright, no lo incluiré aquí, pero está disponible en Github . No lo copie aquí.
Para que las funciones funcionen, deben dejarse con los parámetros genéricos, pero incluyo comentarios que muestran los tipos inferidos dependiendo del uso de las funciones. Esto facilita la comprensión de la función de mantenimiento y deja la función genérica para su uso.
fuente
¡El número de errores es directamente proporcional al número de caracteres en un programa!
Esto generalmente se indica como el número de errores que son proporcionales a las líneas de código. Pero tener menos líneas con la misma cantidad de código da la misma cantidad de errores.
Entonces, aunque es bueno ser explícito, cualquier parámetro adicional que escriba puede provocar errores.
fuente