¿Es la notación húngara una solución para los idiomas con escritura estática insuficientemente expresiva? [cerrado]


28

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 + yBaren 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).


Pascal - aunque si intentas agregar un tipo XCood e YCoord que definiste en Pascal, solo recibirás un aviso de compilación IIRC
mcottle

1
blog.moertel.com/articles/2006/10/18/… es un artículo sobre hacer algo muy similar a las "aplicaciones húngaras" en el sistema de tipos de Haskell.
Logan Capaldo

1
F # tiene esta característica de estilo también.
Rangoric

Ese es un enlace de artículo realmente bueno (The moertel.com) que muestra exactamente el tipo de cosas en las que estaba pensando: usar el sistema de tipos para convertir las vulnerabilidades de seguridad de interpolación de cadenas en errores de tiempo de compilación. Gracias por el enlace.
Ryan C. Thompson

Creo que durante mucho tiempo OO se puso al día con la notación húngara para la semántica, porque hoy probablemente escribirías: Foo.Position.X + Bar.Position.Y.
Pieter B

Respuestas:


27

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:

  1. Esa información es importante.
  2. Esa información no es importante.

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:

ampliar el concepto de "tipo" para abarcar información semántica además de información de representación de almacenamiento.

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).


C, donde la notación húngara era AFAIK más utilizada, sin embargo, no es un lenguaje OO.
Péter Török

44
@ PéterTörök: OO es un patrón de diseño, no una característica de un lenguaje, aunque los lenguajes modernos están diseñados para facilitarlo mientras que C no lo es.
Jan Hudec

3
@ PéterTörök: escribí una gran cantidad de código orientado a objetos en el plano C. Sé de lo que estoy hablando.
Jan Hudec

1
Si bien puede ser cierto que la información importante debe incrustarse en el tipo de una variable en lugar de su nombre, hay muchas cosas importantes que se deben decir, pero que los sistemas de tipos no pueden expresar. Por ejemplo, si S1es la única referencia en cualquier parte del universo a un char[], cuyo titular puede y lo cambiará cuando lo desee, pero nunca debe exponerse a un código externo, y S2es una referencia a una char[]que nadie debería cambiar, pero que puede ser compartida con objetos que prometen no cambiarlo, ¿deberían S1y S2deben considerarse semánticamente como el mismo "tipo de cosa"?
supercat

1
@supercat: está describiendo tipos de unicidad.
Jack

9

¡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 + yBaren 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.


Estar orientado a objetos no es necesario ni suficiente para que un lenguaje permita xFoo + yBartipos definidos por el usuario, ni es necesario el aspecto OO de C ++ para que ese ejemplo funcione.
Luc Danton el

Tienes razón, no es OO, es tipo seguridad. Edité mi respuesta.
BHS

Hmm Es un buen punto que podría cometer xFoo + yBarun 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.
Ryan C. Thompson

En C ++, la verificación de tipo también se realizaría en tiempo de compilación, y la conversión y demás se optimizará en la mayoría de los casos. Java no lo hace tan bien, porque no permite la sobrecarga del operador y demás, por lo que no puede tratar un XCoordinateint como un int regular, por ejemplo.
cHao

5

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.


4

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 uspara una cadena insegura y una cadena ssegura (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 la HtmlStringclase. 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.


2

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)


2

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.


1
Si no me equivoco, esta es otra respuesta que aborda un tipo diferente de notación húngara que la que pregunta el OP.
MatrixFrog

2
Esta respuesta describe lo que se ha llamado "Sistemas húngaros", donde el prefijo denota el "tipo" a nivel de idioma. La pregunta se refiere a "Aplicaciones húngaras", donde la palabra "tipo" no se ha entendido mal y significa el tipo semántico . Systems Hungarian está condenado casi universalmente en estos días (y con razón; es una bastarización del verdadero propósito de la notación húngara). Sin embargo, las aplicaciones húngaras pueden ser algo bueno.
cHao

Los editores capaces de buscar sCustomer sin seleccionar sCustomerName (vi y emacs son 2 ejemplos) han existido desde los años 70.
Larry Coleman

@Larry, tal vez, pero no pudiste hacer que se ejecutaran en los sistemas que estaba programando en los años 80
mcottle

@ cHAo, no, no. Mi punto fue tratar de explicar por qué la gente pone la información adicional en nombres de variables en general. Estudiosamente evité mencionar cualquier versión de notación húngara. Tal vez el ejemplo que di en la sección "por qué buscar y reemplazar no funciona en el código fuente" se parece a "Sistemas húngaros", pero no fue así. He eliminado las "s" iniciales para evitar la confusión.
mcottle

0

¡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.


99
Su respuesta sugiere que no comprende la diferencia entre el original e inteligente "Apps" húngaro y la tonta bastarización llamada "Systems" Hungarian. Lea joelonsoftware.com/articles/Wrong.html
Ryan Culpepper el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.