En el artículo de Eric Lippert ¿Qué pasa con la notación húngara? , afirma que el propósito de la notación húngara (el buen tipo) es
ampliar el concepto de "tipo" para abarcar información semántica además de información de representación de almacenamiento.
Un ejemplo simple sería prefijar una variable que representa una coordenada X con "x" y una variable que representa una coordenada Y con "y", independientemente de si esas variables son números enteros o flotantes o lo que sea, de modo que cuando escriba accidentalmente xFoo + yBar
, el código claramente se ve mal.
Pero también he estado leyendo sobre el sistema de tipos de Haskell, y parece que en Haskell, uno puede lograr lo mismo (es decir, "ampliar el concepto de tipo para abarcar la información semántica") utilizando tipos reales que el compilador verificará por usted. Entonces, en el ejemplo anterior, xFoo + yBar
en Haskell en realidad no se compilaría si diseñara su programa correctamente, ya que se declararían como tipos incompatibles. En otras palabras, parece que el sistema de tipos de Haskell admite efectivamente la verificación en tiempo de compilación equivalente a la notación húngara
Entonces, ¿la notación húngara es solo una curita para los lenguajes de programación cuyos sistemas de tipos no pueden codificar información semántica? ¿O la notación húngara ofrece algo más allá de lo que puede ofrecer un sistema de tipo estático como el de Haskell?
(Por supuesto, estoy usando Haskell como ejemplo. Estoy seguro de que hay otros lenguajes con sistemas de tipo similarmente expresivos (¿ricos? ¿Fuertes?), Aunque no he encontrado ninguno).
Para que quede claro, estoy no hablando de anotar los nombres de variables con la información de tipo, sino más bien con la información sobre el significado de la variable en el contexto del programa. Por ejemplo, una variable puede ser un número entero o flotante o doble o largo o lo que sea, pero tal vez el significado de la variable es que es una coordenada x relativa medida en pulgadas. Este es el tipo de información sobre la que estoy hablando de codificación a través de la notación húngara (y los tipos de Haskell).
fuente
Respuestas:
Yo diría que sí".
Como usted dice, el propósito de la notación húngara es codificar información en el nombre que no se puede codificar en el tipo. Sin embargo, básicamente hay dos casos:
Comencemos con el caso 2 primero: si esa información no es importante, entonces la notación húngara es simplemente un ruido superfluo.
El caso más interesante es el número 1, pero diría que si la información es importante, debe verificarse, es decir, debe ser parte del tipo , no del nombre .
Lo que nos lleva de vuelta a la cita de Eric Lippert:
En realidad, eso no es "extender el concepto de tipo", ¡ese es el concepto de tipo! ¡El propósito completo de los tipos (como herramienta de diseño) es codificar información semántica! La representación de almacenamiento es un detalle de implementación que generalmente no pertenece en absoluto al tipo . (Y específicamente en un lenguaje OO no puede pertenecer al tipo, ya que la independencia de representación es uno de los requisitos previos principales para OO).
fuente
S1
es la única referencia en cualquier parte del universo a unchar[]
, cuyo titular puede y lo cambiará cuando lo desee, pero nunca debe exponerse a un código externo, yS2
es una referencia a unachar[]
que nadie debería cambiar, pero que puede ser compartida con objetos que prometen no cambiarlo, ¿deberíanS1
yS2
deben considerarse semánticamente como el mismo "tipo de cosa"?¡El propósito de los tipos (como herramienta de diseño) es codificar información semántica!
Me gustó esta respuesta y quería seguirla ...
No sé nada sobre Haskell, pero puede lograr algo como el ejemplo
xFoo + yBar
en cualquier lenguaje que admita algún tipo de seguridad de tipo, como C, C ++ o Java. En C ++ podría definir clases XDir e YDir con operadores '+' sobrecargados que solo toman objetos de su propio tipo. En C o Java, necesitaría hacer su adición usando una función / método add () en lugar del operador '+'.Siempre he visto la notación húngara utilizada para información de tipo, no semántica (excepto en la medida en que la semántica podría estar representada por tipo). Una forma conveniente de recordar el tipo de variable en los días previos a los editores de programación "inteligentes" que muestran el tipo de una manera u otra directamente en el editor.
fuente
xFoo + yBar
tipos definidos por el usuario, ni es necesario el aspecto OO de C ++ para que ese ejemplo funcione.xFoo + yBar
un error de compilación (o al menos un error de tiempo de ejecución) en casi cualquier idioma. Sin embargo, ¿las matemáticas con las clases XDir e YDir en, por ejemplo, Java o C ++ serían más lentas que las matemáticas con números sin procesar? Tengo entendido que en Haskell, los tipos se verifican en tiempo de compilación, y luego en tiempo de ejecución, sería matemática en bruto sin verificación de tipo y, por lo tanto, no es más lento que agregar números regulares.XCoordinate
int como un int regular, por ejemplo.Me doy cuenta de que la frase "notación húngara" ha llegado a significar algo diferente al original , pero responderé "no" a la pregunta. Nombrar variables con tipo semántico o computacional no hace lo mismo que escribir con estilo SML o Haskell. Ni siquiera es una curita. Tomando C como ejemplo, podría nombrar una variable gpszTitle, pero esa variable podría no tener un alcance global, incluso podría no constituir un punto para una cadena terminada en nulo.
Creo que las notaciones húngaras más modernas tienen una divergencia aún mayor de un sistema de deducción de tipo fuerte, porque mezclan información "semántica" (como "g" para global o "f" para bandera) con el tipo computacional (puntero "p", " i "entero, etc., etc.) Eso termina como un desastre profano en el que los nombres de las variables tienen una vaga semejanza con su tipo computacional (que cambia con el tiempo) y todos se ven tan similares que no puede usar" siguiente coincidencia "para encontrar una variable en una función particular: todas son iguales.
fuente
La notación húngara se inventó para BCPL, un idioma que no tenía tipos en absoluto. O más bien, tenía exactamente un tipo de datos, la palabra. Una palabra podría ser un puntero o podría ser un carácter o un número booleano o entero entero dependiendo de cómo lo usó. Obviamente, esto hizo que fuera muy fácil cometer errores horribles, como desreferenciar a un personaje. Entonces, se inventó la notación húngara para que el programador al menos pudiera realizar una verificación manual de tipos mirando el código.
C, un descendiente de BCPL, tiene distintos tipos de enteros, punteros, caracteres, etc. Esto hizo que la notación húngara básica fuera superflua hasta cierto punto (no era necesario codificar en el nombre de la variable si era un int o un puntero), pero la semántica más allá de este nivel aún no se puede expresar como tipos. Esto condujo a la distinción entre lo que se ha llamado "Sistemas" y "Aplicaciones" húngaro. No era necesario expresar que una variable era un int, pero podía usar letras de código para indicar si el int era una coordenada x o y say o un índice.
Los lenguajes más modernos permiten definiciones de tipos personalizados, lo que significa que puede codificar las restricciones semánticas en los tipos, en lugar de en los nombres de variables. Por ejemplo, un lenguaje OO típico tendrá tipos específicos para pares de coordenadas y áreas, por lo que debe evitar agregar una coordenada x a una coordenada y.
Por ejemplo, en el famoso artículo de Joels que alaba las aplicaciones húngaras, usa el ejemplo del prefijo
us
para una cadena insegura y una cadenas
segura (codificada en html), para evitar la inyección de HTML. El desarrollador puede evitar errores de inyección de HTML simplemente inspeccionando cuidadosamente el código y asegurando que los prefijos de las variables coincidan. Su ejemplo está en VBScript, un lenguaje ahora obsoleto que inicialmente no permitía clases personalizadas. En un lenguaje moderno, el problema se puede solucionar con un tipo personalizado, y de hecho esto es lo que Asp.net hace con laHtmlString
clase. De esta forma, el compilador encontrará automáticamente el error, que es mucho más seguro que confiar en el globo ocular humano. Claramente, un lenguaje con tipos personalizados elimina la necesidad de "aplicaciones húngaras" en este caso.fuente
Sí, aunque muchos idiomas que tienen sistemas de tipos lo suficientemente fuertes todavía tienen un problema: la expresibilidad de los nuevos tipos que se basan en / similares a los tipos existentes.
es decir, en muchas langugaes donde podríamos usar el sistema de tipos más, no lo hacemos porque la sobrecarga de crear un nuevo tipo que sea básicamente igual a un tipo existente que no sea nombre y un par de funciones de conversión es demasiado grande.
Esencialmente necesitamos algún tipo de typedefs fuertemente tipados para eliminar completamente la notación húngara en estos idiomas (UM estilo F # también podría hacerlo)
fuente
Recuerde, hubo un momento en que los IDE no tenían sugerencias emergentes que le indicaban qué tipo de variable es. Hubo un momento en que los IDE no entendían el código que estaban editando, por lo que no podía pasar fácilmente del uso a la declaración. También hubo un momento en el que no se podía refactorizar un nombre de variable sin pasar manualmente por toda la base de código, realizar el cambio a mano y esperar que no se lo perdiera. No pudo utilizar la búsqueda y reemplazo porque la búsqueda de Cliente también le da Nombre de cliente ...
En aquellos días oscuros, fue útil saber de qué tipo era una variable donde se usaba. Si se mantiene adecuadamente (un GRANDE si se debe a la falta de herramientas de refactorización), la notación húngara le dio eso.
El costo en estos días de los horribles nombres que produce es demasiado alto, pero eso es algo relativamente reciente. Todavía existe mucho código que es anterior a los desarrollos de IDE que he descrito.
fuente
¡Correcto!
Fuera de los idiomas totalmente sin tipo, como Assembler, la notación húngara es superflua y molesta. Doblemente cuando consideras que la mayoría de los IDE verifican la seguridad de los tipos a medida que escribes.
La "i" "d" y "?" Adicionales los prefijos solo hacen que el código sea menos legible y pueden ser realmente engañosos, como cuando un "orker" cambia el tipo de iaSumsItems de Integer a Long pero no se molesta en refactorizar el nombre del campo.
fuente