Hace poco salió en Twitter la discusión sobre si se debe o no de usar la nomenclatura húngara en Objective C. Fue una gran sorpresa para mí, porque fue como ver a un zombie salir de su tumba a la cual lo creías relegado y olvidado desde hace años (¿décadas?).
La mejor respuesta a esa pregunta la ha dado Linus Torvalds en su
Linux Kernel Coding Style:
“Encoding the type of a function into the name (so-called Hungarian notation) is brain damaged—the compiler knows the types anyway and can check those, and it only confuses the programmer.”
Podríamos dejarlo ahí sin más, pero como tengo algo de insomnio, me explayaré un poquito más.
¿Qué encontrarás en este post?
Toggle¿Qué es la nomenclatura húngara?
Empecemos por ahí: ¿qué coño es la nomenclatura húngara y por qué demonios se llama “húngara”?
En pocas palabras (la paja mental completa es bastante más compleja), la nomenclatura húngara consiste en poner un prefijo a los nombres de las variables, especificando su tipo. Por ejemplo, si tenías una variable que representase un precio, no bastaría con llamarla “price”, sino que había que especificar que se trataba de un número de coma flotante con “fpPrice”.
Otros ejemplos serían:
- bDirty o fDirty: un booleano o un “flag”, como prefieras
- pData: un puntero
- fnStringify: una función
- aulTimes: un array de unsigned long (la cosa empieza a ponerse chunga)
- hWndMainWindow: un Window Handle (muy común en desarrollo Win32)
- iCounter: Un índice o entero
Ahora bien, si ya tenemos una idea de en qué consiste la aberración en cuestión, ¿por qué se le ha echado la culpa a los pobres húngaros?
Esta convención fue perpetrada por un tal Charles Simonyi, antiguo empleado de Microsoft y de origen húngaro.
Decimos las malas lenguas que lo de “húngara” no viene por la nacionalidad del culpable, sino porque los nombres de las variables terminan siendo tan ininteligibles como el idioma húngaro.
La nomenclatura húngara en Microsoft
Durante un tiempo, esta práctica alcanzó un estatus casi religioso en Microsoft y entre los desarrolladores de Windows. Gran parte de la culpa la tuvo Petzold en su biblia de Win32, con la cual introdujo ese “meme” infernal en la mente de tantos programadores.
Hoy por hoy está en desuso e incluso la propia Microsoft, arrepentida de sus pasados pecados, recomienda NO usarla en desarrollo .NET.
Por qué se creó la nomenclatura húngara.
Cuando se creó la nomenclatura húngara, estaba pensado para ser usada en lenguajes fuertemente tipados y con una ausencia casi total de IDEs que te diesen información sobre cualquier símbolo de tu código.
No era del todo una mala idea, pero fue pésimamente usada y llevada a extremos ridículos. Por si fuera poco, se aplicó a lenguajes en los cuales no tenía ningún sentido.
Por qué no debes de usar la nomenclatura húngara
Hay varias razones por las cuales no tiene ningún sentido usarla:
Es una solución para un problema inexistente desde hace décadas
Cuando se inventó, la única forma de saber el tipo de una variable, era salir cazando su definición por el código. En cualquier IDE decente, esa información está disponbile con tan solo poner el puntero sobre la variable o, en el peor de los casos, una combinación de teclado que hasta yo puedo recordar.
Contamina tu código con ruido
¿De verdad aporta información el prefijo “str” a “strUserName”?
Fomenta la vagancia a la hora de elegir nombres
Esta es, en mi opinión, la peor consecuencia del uso y abuso de la nomenclatura húngara: fomenta la mala elección de nombres. Como ya has puesto un prefijo, puedes poner cualquier nombre idiota que no aporta ningún tipo de información al lector de tu código.
Puede parecer una exageración, pero he visto con mis ojos, nombres del tipo strString, pPointer y demás. Esto solo indica el tipo de la variable (cosa en general poco importante) y olvida por completo la semántica de la variable (¿un puntero a qué, animal?, ¿una cadena cuyo singificado es el qué, zoquete?).
Si lo que quieres es dar nombres correctos a tus símbolos (variables, funciones y demás), más que seguir a ciegas una convención anticuada y que fomenta malas prácticas, cómprate un buen tesaurus y úsalo cuando tengas dudas.
El que uso yo desde hace eras es el Roget’s Thesaurus of English Words (porque tú nombras tus variables en Inglés, ¿verdad?). Es una herramienta indispensable para quien escribe en Inglés.
De hecho, en mis tiempos Smalltalkeros, me hice un plugin para Dolphin Smalltalk que consultaba con un tesaurus online y te daba sinónimos y palabras relacionadas al texto seleccionado.
¿Por qué usar la nomenclatura húngara en Objective C es una aberración?
Ya hemos visto que la nomenclatura húngara es, en el mejor de los casos, una pérdida de tiempo en cualquier lenguaje. Sin embargo, usarlo en Objective C es una herejía abominable, puesto que implica en ignorar una de las características que definen el lenguaje.
Repasemos: la nomenclatura húngara sirve para indicar el tipo de una variable. Pues bien, una de las características que definen a Objective C (y a otros lenguajes dinámicos) es que ¡las variables NO tienen tipo!
En Objective C sólo los valores tienen tipo, nunca las variables.
Alguno podrá pensar que al escribir código como este,
NSString *name = @"Ilona Staller";
está creando una variable llamada name y de tipo puntero a NSString… ¡pues no!
[[NSPolla defaultPolla] isEqual: [NSOlla reallyBigOlla]];
Si cambias ese código por el siguiente,
id name = @"Ilona Staller";
¡el compilador creará exactamente el mismo código!
Es decir, si quisieras, podrías olvidarte de indicar el tipo de tus variables y definir todos tus objetos como id. Al compilador le da igual.
Esas variables “tipadas” sólo existen para ayudarte a ti a cazar gazapos y despistes tontos, pero para el lenguaje, todos son objetos en general y su tipado se averigua en tiempo de ejecución.
Duck Typing o tipado del pato
Este hecho es algo que el compilador te ha estado indicando siempre, pero lo más probable es que jamás hayas prestado atención a las pistas.
Por ejemplo, ¿por qué al definir un método que acepta una cadena tenemos que poner el tipo del parámetro entre paréntesis?
-(void)setUserName:(NSString *)aName;
¿Por qué (NSString *) aName y no NSString *name? ¿Qué sentido tienen esos paréntesis?
No es una simple convención, si quitas esos paréntesis, no compilará.
Parece una tontería, pero recordad, no estamos en C++, sino Objective C (¡esto es Objective C!). Es decir, la sintaxis está bien pensada, o al menos, bien copiada de Smalltalk.
¿Qué nos quiere decir el lenguaje con esa sintaxis (NSString *)? Para entenderlo, hay que repasar nuestros conocimientos de C: ¿no parece eso un cast a un puntero a NSString?
Esa exactamente es la pista que nos da el lenguaje: precisamente está diciendo que NO acepta un puntero a NSString, sino cualquier cosa que se pueda castear a un puntero a NSString.
Es decir, aceptará cualquier cosa que entienda los mensajes que entiende un NSString. Da igual si resulta ser un NSFileManager disfrazado: si entiende los mensajes de NSString, lo demás no importa.
It isn’t inheritance that makes all sorts of things available
to the user, it is conformance to common interfaces. — Richard O’Keefe
Esto precisamente es el “tipado del pato”: si algo camina como un pato, hace ruido de pato y parece un pato, pues será un pato. Da igual que luego resulte ser un pollo disfrazado, lo que importa es que se comporta como un pato.
Por lo tanto, si en Objective C las variables NO tienen tipo, ¿tiene sentido meter en fregados húngaros para indicar un tipado que no existe?
Conclusión
Hungría tiene muchas cosas buenas, como Ilona Staller, el vino de Tokaji y la literatura, como “Las cárceles del alma” de Lajos Zilahy; pero la perversión de Simonyi no está entre ellas.
A no ser que sea por razones nostálgicas, no tiene ningún sentido usar la nomenclatrua húngara.
Si quieres elegir siempre buenos nombres para tus variables, ten siempre a mano el Roget’s.
Si te va lo húngaro, bájate las pelis de la Cicciolina y tómate una botella de Tokaji Aszú de 6 “Putones” a mi salud.
Si te va lo retro y lo nostálgico, déjate de mamandurrias y échale huevos: programa en Cobol como @jmoreno78 o en Snobol4 como yo. La cosa parecerá tan absurda y delirante que nadie se lo tomará en serio, pensando que eres un carcamal perturbado, sino un fino humorista y un cachondo mental.