Pourquoi ne devrais-je pas utiliser la «notation hongroise»?

122

Je sais à quoi le hongrois se réfère - donner des informations sur une variable, un paramètre ou un type comme préfixe de son nom. Tout le monde semble être farouchement contre, même si dans certains cas cela semble être une bonne idée. Si je sens que des informations utiles sont transmises, pourquoi ne les placerais-je pas là où elles sont disponibles?

Voir aussi: Les gens utilisent-ils les conventions de dénomination hongroises dans le monde réel?

Shog9
la source
En relation: stackoverflow.com/questions/202107/…
Lance Roberts

Réponses:

174

La plupart des gens utilisent la notation hongroise de manière incorrecte et obtiennent de mauvais résultats.

Lisez cet excellent article de Joel Spolsky: Making Wrong Code Look Wrong .

En bref, la notation hongroise où vous préfixez vos noms de variables avec leur type(chaîne) (hongrois systèmes) est mauvaise car elle est inutile.

Notation hongroise telle qu'elle a été conçue par son auteur où vous préfixez le nom de la variable avec son kind(en utilisant l'exemple de Joel: chaîne sûre ou chaîne non sécurisée), ce qu'on appelle Apps hongrois a ses utilisations et est toujours valable.

Ilya Kochetov
la source
5
Bon lien, un bon résumé de ce qui se cache derrière le lien et aucun fanatisme. Excellent.
Dustman
12
Notez que l'exemple de Joels est en VBScript, un langage qui n'a pas longtemps eu de classes définies par l'utilisateur. Dans un langage OO, vous créez simplement un type HtmlEncodedString et la méthode Write accepte uniquement cela. Les "Apps hongroises" ne sont utiles que dans les langues sans types définis par l'utilisateur.
JacquesB
4
Microsoft est connu pour son utilisation abusive de la notation hongroise dans le passé. La prépension des informations de type aux identifiants est non seulement inutile, mais elle peut en fait faire du mal. Premièrement, la lisibilité est moins courante. Deuxièmement, dans les langues qui prennent en charge le polymorphisme ou le typage canard, les mauvaises informations sont transmises.
wilhelmtell
9
J'aime toujours utiliser la notation hongroise si je fais du développement C avec un IDE plus ancien ... de cette façon, je sais qu'il n'y a pas de problèmes de conversion de type.
Bip bip
3
@Krumia: Cela serait généralement évité en ayant des noms de variables descriptifs en premier lieu. Mais si vous voulez être sûr, il serait beaucoup plus sûr de créer des types distincts (par exemple des structures) pour les longueurs, les poids, etc. et d'utiliser la surcharge d'opérateurs pour garantir que seules des opérations valides sont possibles.
JacquesB
277

vUtiliser adjHungarian nnotation v rend la lecture de ncode adjdifficile.

Marquer le stock
la source
101
Belle analogie, bien que légèrement injuste. Comparez: vUsing adjHungarian nNotation vRend nReading nCode adjDifficult.
Chris Noe
27
Dans cette phrase, utiliser et lire sont des gérondifs. Mais je comprends ce que vous vouliez dire ...
chimp
28
@chimp: cela rend les choses encore plus évidentes. maintenant que vous avez trouvé une erreur dans le type, allez-vous renommer toutes les références ou les laisser telles quelles, en fournissant des informations erronées? vous perdez de toute façon. mais bien sûr, c'est la MAUVAISE façon d'appliquer la notation hongroise.
wilhelmtell
1
@Chris Noe: pour certains styles de lecture (analysez le préfixe et le suffixe avec un coup d'œil au milieu), votre exemple ne fait qu'empirer les choses. Je vois «vUsing» et j'entends «voosing» dans ma tête.
Bob Cross
3
@Jon: si vous avez un nom de variable qui ne révèle pas complètement ce qu'il représente, alors l'objectif devrait absolument être de le renommer en quelque chose de plus descriptif (et la notation hongroise n'est pas une amélioration, dans le très, très dans le meilleur des cas, il corrige le symptôme - ne résout pas le problème).
hlovdal
104

Joel a tort, et voici pourquoi.

Ces informations "d'application" dont il parle doivent être encodées dans le système de types . Vous ne devez pas dépendre du retournement des noms de variables pour vous assurer de ne pas transmettre de données dangereuses aux fonctions nécessitant des données sûres. Vous devez en faire une erreur de type, de sorte qu'il soit impossible de le faire. Toutes les données non sécurisées doivent avoir un type marqué comme non sécurisé, afin qu'elles ne puissent tout simplement pas être transmises à une fonction sécurisée. Pour passer de dangereux à sûr, il faut un traitement avec une sorte de fonction de désinfection.

Beaucoup de choses dont Joel parle comme "sortes" ne sont pas des sortes; ce sont, en fait, des types.

Ce qui manque à la plupart des langues, cependant, c'est un système de types suffisamment expressif pour imposer ce genre de distinctions. Par exemple, si C avait une sorte de "strong typedef" (où le nom typedef avait toutes les opérations du type de base, mais n'était pas convertible en lui) alors beaucoup de ces problèmes disparaîtraient. Par exemple, si vous pouviez dire, strong typedef std::string unsafe_string;pour introduire un nouveau type unsafe_stringqui ne pourrait pas être converti en std :: string (et pourrait donc participer à la résolution de surcharge, etc.), nous n'aurions pas besoin de préfixes idiots.

Ainsi, l'affirmation centrale selon laquelle le hongrois est pour des choses qui ne sont pas des types est fausse. Il est utilisé pour les informations de type. Informations de type plus riches que les informations de type C traditionnelles, certainement; c'est une information de type qui encode une sorte de détail sémantique pour indiquer le but des objets. Mais ce sont toujours des informations de type, et la solution appropriée a toujours été de les encoder dans le système de types. L'encoder dans le système de types est de loin le meilleur moyen d'obtenir une validation et une application appropriées des règles. Les noms de variables ne coupent tout simplement pas la moutarde.

En d'autres termes, le but ne doit pas être de "faire en sorte que le mauvais code semble faux pour le développeur". Cela devrait être "rendre le code erroné pour le compilateur ".

DrPizza
la source
30
L'intention de la variable doit être codée dans le type de la variable, et non laissée à quelque chose d'aussi fragile qu'un schéma de dénomination insensé.
DrPizza
3
J'adorerais en faire le travail du compilateur / interprète aussi, mais cela entraînerait une surcharge énorme pour les langages dynamiques (Python, Ruby, PHP ou Javascript).
trop de php
22
«Ce qui manque à la plupart des langues, cependant, c'est un système de types suffisamment expressif pour imposer ce genre de distinctions» Et c'est là que réside le problème. AppsHungarian est une méthode pragmatique pour mettre en évidence les problèmes lors de l'utilisation de ces langues de manière évidente pour les programmeurs qui visualisent le code, plutôt que d'examiner les rapports de bogues.
Neil Trodden
6
@DrPizza: Je pense que vous avez manqué l'un des points très importants que Joel fait valoir en préconisant les applications hongroises: cette notation est juste un compromis très pragmatique . Rendre le compilateur capable de voir le "mauvais code" est un grand objectif, mais vaut-il toujours son coût?
Yarik
4
@DrPizza: Joel is wronget What most languages lack, however, is a type system that's expressive enough to enforce these kind of distinctions.donc, étant donné que la plupart des langues ne manquent suffisamment expressivité pour faire appliquer ce genre de distinctions, Joel est juste. Droite?
sampathsris
46

Je pense que cela encombre massivement le code source.

Cela ne vous rapporte pas non plus beaucoup dans un langage fortement typé. Si vous faites n'importe quelle forme de type mismatch tomfoolery, le compilateur vous en parlera.

nsanders
la source
Sensationnel. 90 répétitions en 15 minutes. Bon appel.
Dustman
2
Si vous l'utilisez pour le type, alors oui, c'est inutile. Il est utile de communiquer d'autres informations.
Lou Franco
12
@Lou, exactement - personnellement, je stocke un historique des révisions dans mes noms de variables: string firstName_wasName_wasNameID_wasSweetCupinCakes
Shog9
@nsanders: essayez d'utiliser le compilateur pour vérifier si vous avez utilisé les mêmes unités de mesure lorsque les deux types de variables sont des nombres entiers.
Igor Levicki
1
@ Shog9: Je pense que vous n'avez pas compris la notation hongroise Apps. Il s'agit plus de sFirstName vs unFirstName (sûr vs non sûr, non désinfecté), de cette façon, vous en savez quelque chose de plus. Pourtant, je pense que dans les langages statiques, il est préférable de sous-taper String pour créer UnsafeString et SafeString et autoriser uniquement SafeString à sortir. La convention est correcte, mais (plus souvent) les applications de compilation sont meilleures.
kgadek
28

La notation hongroise n'a de sens que dans les langues sans types définis par l'utilisateur . Dans un langage fonctionnel ou OO moderne, vous encoderiez des informations sur le «genre» de valeur dans le type de données ou la classe plutôt que dans le nom de la variable.

Plusieurs réponses font référence à l' article de Joels . Notez cependant que son exemple est en VBScript, qui ne supportait pas les classes définies par l'utilisateur (pendant longtemps au moins). Dans un langage avec des types définis par l'utilisateur, vous résoudriez le même problème en créant un type HtmlEncodedString, puis en laissant la méthode Write accepter uniquement cela. Dans un langage typé statiquement, le compilateur détectera toutes les erreurs de codage, dans un langage typé dynamiquement, vous obtiendrez une exception d'exécution - mais dans tous les cas, vous êtes protégé contre l'écriture de chaînes non codées. Les notations hongroises transforment simplement le programmeur en un vérificateur de type humain, avec le genre de travail qui est généralement mieux géré par un logiciel.

Joel fait la distinction entre «systèmes hongrois» et «apps hongrois», où «systèmes hongrois» encode les types intégrés tels que int, float, etc., et «apps hongrois» encode «genres», qui est une méta-info de plus haut niveau à propos de la variable au-delà du type de machine, dans un langage OO ou fonctionnel moderne, vous pouvez créer des types définis par l'utilisateur, il n'y a donc pas de distinction entre type et «genre» dans ce sens - les deux peuvent être représentés par le système de types - et «applications» le hongrois est tout aussi redondant que les "systèmes" hongrois.

Donc, pour répondre à votre question: les systèmes hongrois ne seraient utiles que dans un langage peu sûr et faiblement typé où, par exemple, attribuer une valeur flottante à une variable int planterait le système. La notation hongroise a été spécifiquement inventée dans les années 60 pour être utilisée dans BCPL , un langage assez bas niveau qui ne faisait aucun contrôle de type. Je ne pense pas qu'aucun langage couramment utilisé aujourd'hui ait ce problème, mais la notation a survécu comme une sorte de programmation culte du fret .

Les applications hongroises auront du sens si vous travaillez avec un langage sans types définis par l'utilisateur, comme l'ancien VBScript ou les premières versions de VB. Peut-être aussi les premières versions de Perl et PHP. Encore une fois, l'utiliser dans un langage moderne est un pur culte du cargo.

Dans n'importe quelle autre langue, le hongrois est juste laid, redondant et fragile. Il répète des informations déjà connues du système de types et vous ne devez pas vous répéter . Utilisez un nom descriptif pour la variable qui décrit l'intention de cette instance spécifique du type. Utilisez le système de types pour encoder les invariants et les méta-informations sur les «genres» ou «classes» de variables - ie. les types.

Le point général de l'article de Joels - avoir un code erroné - est un très bon principe. Cependant, une protection encore meilleure contre les bogues consiste - lorsque cela est possible - à avoir un code erroné à détecter automatiquement par le compilateur.

JacquesB
la source
Les langages avec des types définis par l'utilisateur ne rendent pas toujours pratique l'utilisation de types au lieu de "genres". Considérez les préfixes "c", "d", "ix" de Joel's Apps hongrois. Utilisez-vous des types entiers personnalisés pour ceux-ci, dans toutes les langues modernes? Je ne pense pas. Parce que les langues modernes n'ont toujours pas de types d'entiers personnalisés intégrés pour les indices, les nombres et les différences entre deux nombres. Tant que nous utilisons encore des ints vanille, les applications hongroises seront non redondantes et utiles.
Eldritch Conundrum
27

J'utilise toujours la notation hongroise pour tous mes projets. Je trouve cela très utile lorsque je traite des centaines de noms d'identificateurs différents.

Par exemple, lorsque j'appelle une fonction nécessitant une chaîne, je peux taper «s» et appuyer sur l'espace de contrôle et mon IDE me montrera exactement les noms de variables précédés de «s».

Un autre avantage, quand je préfixe u pour unsigned et i pour sign ints, je vois immédiatement où je mélange les signés et les non-signés de manière potentiellement dangereuse.

Je ne me souviens pas du nombre de fois où dans une énorme base de code de 75000 lignes, des bogues ont été causés (par moi et d'autres aussi) en raison du nom des variables locales de la même manière que les variables membres existantes de cette classe. Depuis, je préfixe toujours les membres avec 'm_'

C'est une question de goût et d'expérience. Ne le frappez pas avant de l'avoir essayé.

rep_movsd
la source
1
L'encodage de la signature en noms de variables est excellent lorsque le morceau de code traite réellement de la signature. Utiliser cela comme une excuse pour appliquer la convention pour toutes les variables est juste le domatisme à mon humble avis.
Plumenator
Vous avez cependant un bon point avec les variables membres. Mais dans des langages comme Python où vous êtes obligé de qualifier les membres avec le self / this object, c'est inutile.
Plumenator
C'est juste une astuce pour améliorer la productivité. Tout comme la saisie semi-automatique IDE. Il n'y a rien de fondamentalement mauvais à ce sujet. Je pense que les codeurs expérimentés doivent être autorisés à utiliser leur propre style. Forcer quiconque à choisir un certain style est mauvais. Je travaille en tant que développeur unique maintenant, mais je n'appliquerais pas de style à quiconque avec qui j'ai travaillé à moins qu'il ne manque un style cohérent au départ.
rep_movsd
Donc, vous utilisez la convention de dénomination a pour filtrer les variables, hein? Je dois convenir que c'est un peu intelligent . :-) Cependant, la façon dont je suis câblé, le point d'ancrage (ou critère de filtre, si vous le souhaitez) est toujours la sémantique pour moi. Rarement le type (sauf s'il s'agit de la sémantique). J'espère que cela a du sens. TL; DR: Je m'en tiendrai toujours à nommer les variables en fonction de ce qu'elles représentent plutôt que de la façon dont elles sont représentées.
Pluménateur le
1
J'ai voté pour cela à l'époque car j'étais en faveur du hongrois. Maintenant, je le regrette et je ne retournerais jamais au préfixe de quelque chose à une variable ..
nawfal
22

Vous oubliez la raison numéro un pour inclure ces informations. Cela n'a rien à voir avec vous, le programmeur. Cela a tout à voir avec la personne qui arrive sur la route 2 ou 3 ans après avoir quitté l'entreprise qui doit lire ce genre de choses.

Oui, un IDE identifiera rapidement les types pour vous. Cependant, lorsque vous lisez de longs lots de code de «règles métier», il est agréable de ne pas avoir à faire une pause sur chaque variable pour savoir de quel type il s'agit. Quand je vois des choses comme strUserID, intProduct ou guiProductID, il en fait beaucoup plus facile « montée en puissance » du temps.

Je conviens que MS est allé trop loin avec certaines de leurs conventions de dénomination - je classe cela dans la pile «trop de bonnes choses».

Les conventions de dénomination sont de bonnes choses, à condition que vous vous y teniez. J'ai parcouru suffisamment de code ancien qui me faisait constamment revenir en arrière pour regarder les définitions de tant de variables portant le même nom que je pousse "camel casing" (comme on l'appelait lors d'un travail précédent). En ce moment, je travaille avec des milliers de lignes de code ASP classique complètement non commenté avec VBScript et c'est un cauchemar d'essayer de comprendre les choses.

David
la source
En tant qu'utilisateur VIM (pas d'IDE, pas de mise en évidence, pas de hover-tell-you-what-type), je ne comprends pas du tout cet argument. Je comprends naturellement qu'une variable appelée name est une chaîne, et une variable appelée i ou count est un int. A-t-on vraiment besoin de sName et d'iCount? Comment cela aide-t-il vraiment? Je dirais que votre exemple d'identification de produit est un cas particulier, et peut-être que ce serait bien. Mais même dans ce cas, être cohérent et représenter les ID de produit avec des entiers ou des chaînes partout serait une bien meilleure solution, non? Toute la question de nommer semble être une échappatoire.
MrFox
6
C'est pour la cohérence. Oui, "nom" implique intrinsèquement une chaîne. Mais que supposeriez-vous que "userid" soit? UN GUID? Chaîne? Entier? Même quelque chose comme "acctno" pourrait avoir une valeur de 42 ou "23X". La documentation est assez rare dans la plupart des codes. Cette norme aide un peu le programmeur de maintenance.
David
1
@David Je suis tout à fait d'accord avec votre réponse - connaître en un coup d'œil l'intention de la variable est la raison pour laquelle je préfère également le préfixe, plus encore dans un langage dynamique comme JS.
Daniel Sokolowski
10

S'attaquer aux caractères cryptiques au début de chaque nom de variable n'est pas nécessaire et montre que le nom de la variable en lui-même n'est pas assez descriptif. La plupart des langages nécessitent de toute façon le type de variable lors de la déclaration, de sorte que les informations sont déjà disponibles.

Il y a aussi la situation où, pendant la maintenance, un type de variable doit changer. Exemple: si une variable déclarée comme "uint_16 u16foo" doit devenir non signée 64 bits, l'une des deux choses suivantes se produira:

  1. Vous passerez en revue et modifierez chaque nom de variable (en vous assurant de ne pas utiliser de variables non liées avec le même nom), ou
  2. Changez simplement le type et ne changez pas le nom, ce qui ne fera que semer la confusion.
coledot
la source
9

Joel Spolsky a écrit un bon article de blog à ce sujet. http://www.joelonsoftware.com/articles/Wrong.html Fondamentalement, cela revient à ne pas rendre votre code plus difficile à lire lorsqu'un IDE décent vous dira que vous voulez taper la variable si vous ne vous en souvenez pas. De plus, si vous rendez votre code suffisamment compartimenté, vous n'avez pas à vous rappeler quelle variable a été déclarée trois pages plus haut.

Paul Tomblin
la source
9

La portée n'est-elle pas plus importante que le type de nos jours, par exemple

* l for local
* a for argument
* m for member
* g for global
* etc

Avec les techniques modernes de refactorisation de l'ancien code, la recherche et le remplacement d'un symbole parce que vous avez changé son type est fastidieux, le compilateur détectera les changements de type, mais souvent ne détectera pas l'utilisation incorrecte de la portée, des conventions de dénomination judicieuses aident ici.

titanes
la source
Là encore, le code ne devrait probablement pas dépendre autant de la portée. :-)
Plumenator
8

Il n'y a aucune raison pour laquelle vous ne devriez pas utiliser correctement la notation hongroise. Son impopularité est due à un contrecoup de longue date contre la mauvaise utilisation de la notation hongroise, en particulier dans les API Windows.

Dans le mauvais vieux temps, avant que quelque chose ressemblant à un IDE n'existait pour DOS (il y a de fortes chances que vous n'ayez pas assez de mémoire libre pour exécuter le compilateur sous Windows, donc votre développement a été fait sous DOS), vous n'avez obtenu aucune aide de en passant la souris sur un nom de variable. (En supposant que vous ayez une souris.) Ce que vous aviez à gérer, ce sont les fonctions de rappel d'événement dans lesquelles tout vous était passé sous forme d'un entier 16 bits (WORD) ou d'un int 32 bits (MOT LONG). Vous deviez ensuite convertir ces paramètres en types appropriés pour le type d'événement donné. En fait, une grande partie de l'API était pratiquement sans type.

Le résultat, une API avec des noms de paramètres comme ceux-ci:

LRESULT CALLBACK WindowProc(HWND hwnd,
                            UINT uMsg,
                            WPARAM wParam,
                            LPARAM lParam);

Notez que les noms wParam et lParam, bien qu'assez horribles, ne sont pas vraiment pires que de les nommer param1 et param2.

Pour aggraver les choses, Windows 3.0 / 3.1 avait deux types de pointeurs, proche et lointain. Ainsi, par exemple, la valeur de retour de la fonction de gestion de la mémoire LocalLock était un PVOID, mais la valeur de retour de GlobalLock était un LPVOID (avec le «L» pendant longtemps). Cette notation terrible alors obtenu afin que l'intervalle l de p était préfixé ointer chaîne lp , pour le distinguer d'une chaîne qui avait malloc'd simplement été.

Il n'est pas surprenant qu'il y ait eu une réaction contre ce genre de chose.

dgvid
la source
6

La notation hongroise peut être utile dans les langages sans vérification de type au moment de la compilation, car elle permettrait au développeur de se rappeler rapidement comment la variable particulière est utilisée. Cela ne fait rien pour les performances ou le comportement. Il est censé améliorer la lisibilité du code et est principalement une question de goût et de style de codage. C'est précisément pour cette raison qu'il est critiqué par de nombreux développeurs - tout le monde n'a pas le même câblage dans le cerveau.

Pour les langages de vérification de type au moment de la compilation, c'est généralement inutile - le défilement de quelques lignes vers le haut devrait révéler la déclaration et donc le type. Si vos variables globales ou votre bloc de code s'étend sur bien plus d'un écran, vous avez de graves problèmes de conception et de réutilisation. Ainsi, l'une des critiques est que la notation hongroise permet aux développeurs d'avoir une mauvaise conception et de s'en tirer facilement. C'est probablement l'une des raisons de la haine.

D'un autre côté, il peut y avoir des cas où même les langages de vérification de type au moment de la compilation bénéficieraient de la notation hongroise - pointeurs vides ou HANDLE dans l'API win32. Ceux-ci obscurcissent le type de données réel, et il pourrait être intéressant d'utiliser la notation hongroise ici. Pourtant, si l'on peut connaître le type de données au moment de la construction, pourquoi ne pas utiliser le type de données approprié.

En général, il n'y a pas de raisons sérieuses de ne pas utiliser la notation hongroise. C'est une question de goûts, de politiques et de style de codage.

Ignas Limanauskas
la source
6

En tant que programmeur Python, la notation hongroise s'effondre assez rapidement. En Python, je ne me soucie pas si quelque chose est une chaîne - je me soucie si cela peut agir comme une chaîne (c'est-à-dire s'il a une ___str___()méthode qui renvoie une chaîne).

Par exemple, disons que nous avons foo comme entier, 12

foo = 12

La notation hongroise nous dit que nous devrions appeler cela iFoo ou quelque chose comme ça, pour désigner que c'est un entier, afin que plus tard, nous sachions ce que c'est. Sauf en Python, cela ne fonctionne pas, ou plutôt, cela n'a pas de sens. En Python, je décide du type que je veux quand je l'utilise. Est-ce que je veux une chaîne? eh bien si je fais quelque chose comme ça:

print "The current value of foo is %s" % foo

Notez la %schaîne -. Foo n'est pas une chaîne, mais l' %opérateur appellera foo.___str___()et utilisera le résultat (en supposant qu'il existe). fooest toujours un entier, mais nous le traitons comme une chaîne si nous voulons une chaîne. Si nous voulons un flotteur, nous le traitons comme un flotteur. Dans les langages dynamiquement typés comme Python, la notation hongroise est inutile, car peu importe le type de quelque chose jusqu'à ce que vous l'utilisiez, et si vous avez besoin d'un type spécifique, assurez-vous simplement de le convertir en ce type (par exemple float(foo)) lorsque vous utilise le.

Notez que les langages dynamiques comme PHP n'ont pas cet avantage - PHP essaie de faire «la bonne chose» en arrière-plan sur la base d'un ensemble obscur de règles que presque personne n'a mémorisées, ce qui entraîne souvent des dégâts catastrophiques de manière inattendue. Dans ce cas, une sorte de mécanisme de dénomination, comme $files_countou $file_name, peut être pratique.

À mon avis, la notation hongroise est comme des sangsues. Peut-être que dans le passé, ils étaient utiles, ou du moins ils semblaient utiles, mais de nos jours, c'est juste beaucoup de frappe supplémentaire pour pas beaucoup d'avantages.

Dan Udey
la source
Il est intéressant de noter que votre exemple avec .str () en Python n'est pas le résultat du langage dynamique. Java, certainement pas un langage dynamique, fait la même chose.
Dustman
C # fait aussi la même chose, chaque classe du langage implémente .ToString()pour que tout puisse être imprimé
Electric Coffee
5

L'EDI devrait transmettre ces informations utiles. Le hongrois aurait pu avoir une sorte de sens (pas beaucoup, mais une sorte) de sens lorsque les IDE étaient beaucoup moins avancés.

Paul Batum
la source
4
Là encore, vous ne devriez pas compter sur l'EDI pour vous en dire plus. Après tout, le code peut être consulté en dehors de l'IDE ...
TraumaPony
5

Applications Le hongrois est grec pour moi - dans le bon sens

En tant qu'ingénieur, pas programmeur, j'ai immédiatement lu l'article de Joel sur les mérites d'Apps hongrois: "Making Wrong Code Look Wrong" . J'aime les applications hongroises car elles imitent la façon dont l'ingénierie, la science et les mathématiques représentent des équations et des formules à l'aide de symboles sous et super-scriptés (comme les lettres grecques, les opérateurs mathématiques, etc.). Prenons un exemple particulier de la loi de Newton sur la gravité universelle : d'abord en notation mathématique standard, puis dans le pseudo-code hongrois Apps:

Loi universelle de gravité de Newton pour la Terre et Mars

frcGravityEarthMars = G * massEarth * massMars / norm(posEarth - posMars)

Dans la notation mathématique, les symboles les plus marquants sont ceux qui représentent le type d'informations stockées dans la variable: force, masse, vecteur de position, etc. Les indices jouent un second violon pour clarifier: position de quoi? C'est exactement ce que fait Apps hongrois; il vous indique d'abord le genre de chose stockée dans la variable et ensuite entrer dans les détails - à propos du code le plus proche peut accéder à la notation mathématique.

Un typage clairement fort peut résoudre l'exemple de chaîne sûr / non sécurisé de l'essai de Joel, mais vous ne définiriez pas des types séparés pour les vecteurs de position et de vitesse; les deux sont des tableaux doubles de taille trois et tout ce que vous êtes susceptible de faire pour l'un peut s'appliquer à l'autre. De plus, il est parfaitement logique de concaténer la position et la vitesse (pour créer un vecteur d'état) ou de prendre leur produit scalaire, mais probablement de ne pas les ajouter. Comment la saisie autoriserait-elle les deux premiers et interdirait la seconde, et comment un tel système s’étendrait-il à toutes les opérations possibles que vous voudriez peut-être protéger? À moins que vous ne vouliez encoder toutes les mathématiques et la physique dans votre système de frappe.

En plus de tout cela, beaucoup d'ingénierie est réalisée dans des langages de haut niveau faiblement typés comme Matlab, ou d'anciens comme Fortran 77 ou Ada.

Donc, si vous avez un langage sophistiqué et que l'IDE et les applications hongrois ne vous aident pas, oubliez-le - beaucoup de gens l'ont apparemment. Mais pour moi, pire qu'un programmeur novice qui travaille dans des langues faiblement ou dynamiquement typées, je peux écrire un meilleur code plus rapidement avec Apps Hongrois que sans.

Adam Wuerl
la source
4

C'est incroyablement redondant et inutile dans la plupart des IDE modernes, où ils font un bon travail pour rendre le type apparent.

De plus - pour moi - c'est juste ennuyeux de voir intI, strUserName, etc. :)

Ian P
la source
3
Comme TraumaPony l'a dit à Paul Batum, tout le monde ne voit pas le code dans l'IDE.
Chris Charabaruk
4

Si je sens que des informations utiles sont transmises, pourquoi ne les placerais-je pas là où elles sont disponibles?

Alors qui se soucie de ce que les autres pensent? Si vous le trouvez utile, utilisez la notation.

Eduffy
la source
Parce qu'il n'y a qu'un seul de moi et un bajillion d'autres personnes qui pourraient maintenir mon code plus tard. Puisque tous ces gens sont dans l'équipe (mais ils ne le savent pas encore), j'aimerais avoir une idée s'ils me surpassent.
Dustman
4

Im mon expérience, c'est mauvais parce que:

1 - alors vous cassez tout le code si vous devez changer le type d'une variable (c'est-à-dire si vous devez étendre un entier de 32 bits à un entier de 64 bits);

2 - ce sont des informations inutiles car le type est soit déjà dans la déclaration, soit vous utilisez un langage dynamique où le type réel ne devrait pas être si important en premier lieu.

De plus, avec un langage acceptant la programmation générique (c'est-à-dire des fonctions où le type de certaines variables ne détermine pas quand vous écrivez la fonction) ou avec un système de typage dynamique (c'est-à-dire quand le type n'est même pas déterminé au moment de la compilation), comment nommeriez-vous votre des variables? Et la plupart des langues modernes prennent en charge l'une ou l'autre, même sous une forme restreinte.

PierreBdR
la source
4

Dans Making Wrong Code Look Wrong de Joel Spolsky, il explique que ce que tout le monde considère comme la notation hongroise (qu'il appelle Systems hongrois) n'est pas ce qu'elle était vraiment censée être (ce qu'il appelle Apps hongrois). Faites défiler jusqu'à la rubrique Je suis Hongrie pour voir cette discussion.

Fondamentalement, les systèmes hongrois ne valent rien. Il vous dit simplement la même chose que votre compilateur et / ou IDE vous dira.

Les applications hongroises vous indiquent ce que la variable est censée signifier et peuvent en fait être utiles.

cjm
la source
4

J'ai toujours pensé qu'un préfixe ou deux au bon endroit ne ferait pas de mal. Je pense que si je peux donner quelque chose d'utile, comme "Hé, c'est une interface, ne comptez pas sur un comportement spécifique" juste là, comme dans IEnumerable, je devrais le faire. Les commentaires peuvent encombrer les choses bien plus qu'un simple symbole à un ou deux caractères.

Dustman
la source
1
Je n'ai jamais eu l'ISomethingable. Si c'est un -able, cela implique quand même une interface. (Au moins en java)
tunaranch
4

C'est une convention utile pour nommer les contrôles sur un formulaire (btnOK, txtLastName, etc.), si la liste des contrôles apparaît dans une liste déroulante alphabétique dans votre IDE.

MusiGenesis
la source
4

J'ai tendance à utiliser la notation hongroise uniquement avec les contrôles serveur ASP.NET , sinon je trouve qu'il est trop difficile de déterminer quels contrôles sont quoi sur le formulaire.

Prenez cet extrait de code:

<asp:Label ID="lblFirstName" runat="server" Text="First Name" />
<asp:TextBox ID="txtFirstName" runat="server" />
<asp:RequiredFieldValidator ID="rfvFirstName" runat="server" ... />

Si quelqu'un peut montrer une meilleure façon d'avoir cet ensemble de noms de contrôle sans le hongrois, je serais tenté d'y passer.

Aaron Powell
la source
4

L'article de Joel est excellent, mais il semble omettre un point majeur:

Le hongrois rend une «idée» particulière (genre + nom d'identifiant) unique, ou presque unique, dans la base de code - même une très grande base de code.

C'est énorme pour la maintenance du code. Cela signifie que vous pouvez utiliser une bonne vieille «recherche de texte sur une seule ligne (grep, findstr,« find in all files ») pour trouver CHAQUE mention de cette« idée ».

Pourquoi est-ce important lorsque nous avons des IDE qui savent lire le code? Parce qu'ils ne sont pas encore très bons dans ce domaine. C'est difficile à voir dans une petite base de code, mais évidente dans une grande base - quand l'idée peut être mentionnée dans des commentaires, des fichiers XML, des scripts Perl, et aussi dans des endroits hors du contrôle des sources (documents, wikis, bases de données de bogues).

Vous devez être un peu prudent même ici - par exemple, le collage de jetons dans les macros C / C ++ peut masquer les mentions de l'identifiant. De tels cas peuvent être traités en utilisant des conventions de codage, et de toute façon ils ont tendance à n'affecter qu'une minorité des identifiants dans la base de code.

PS Au point d'utiliser le système de type par rapport au hongrois - il est préférable d'utiliser les deux. Vous n'avez besoin que d'un code erroné pour avoir une apparence incorrecte si le compilateur ne le détecte pas pour vous. Il existe de nombreux cas où il est impossible de faire en sorte que le compilateur l'attrape. Mais là où c'est faisable - oui, faites-le plutôt!

Lors de l'examen de la faisabilité, cependant, tenez compte des effets négatifs de la division des types. Par exemple, en C #, encapsuler 'int' avec un type non intégré a d'énormes conséquences. Cela a donc du sens dans certaines situations, mais pas dans toutes.

McFig
la source
4

Démystifier les avantages de la notation hongroise

  • Il permet de distinguer les variables.

Si le type est tout ce qui distingue une valeur d'une autre, cela ne peut être que pour la conversion d'un type en un autre. Si vous avez la même valeur qui est convertie entre les types, vous devriez probablement le faire dans une fonction dédiée à la conversion. (J'ai vu des restes de VB6 hongrois utiliser des chaînes sur tous leurs paramètres de méthode simplement parce qu'ils ne pouvaient pas comprendre comment désérialiser un objet JSON, ou comprendre correctement comment déclarer ou utiliser des types Nullable. ) Si vous avez deux variables distinguées uniquement par le Préfixe hongrois, et ils ne sont pas une conversion de l'un à l'autre, vous devez alors préciser votre intention avec eux.

  • Cela rend le code plus lisible.

J'ai trouvé que la notation hongroise rend les gens paresseux avec leurs noms variables. Ils ont quelque chose pour le distinguer, et ils ne ressentent pas le besoin de préciser son objectif. C'est ce que vous trouverez généralement dans le code noté hongrois vs moderne: sSQL vs groupSelectSql ( ou généralement pas de sSQL du tout car ils sont censés utiliser l'ORM qui a été mis par les développeurs précédents. ), SValue vs formCollectionValue ( ou généralement pas de sValue non plus, car ils se trouvent dans MVC et devraient utiliser ses fonctionnalités de liaison de modèle ), sType vs publishSource, etc.

Cela ne peut pas être la lisibilité. Je vois plus de sTemp1, sTemp2 ... sTempN de tout reste de VB6 hongrois donné que tout le monde combiné.

  • Cela évite les erreurs.

Ce serait en vertu du numéro 2, ce qui est faux.

An00bus
la source
3

Dans les mots du maître:

http://www.joelonsoftware.com/articles/Wrong.html

Une lecture intéressante, comme d'habitude.

Extraits:

«Quelqu'un, quelque part, a lu l'article de Simonyi, où il a utilisé le mot« type », et a pensé qu'il voulait dire type, comme classe, comme dans un système de types, comme le type de vérification que le compilateur fait. Il ne l'a pas fait. Il a expliqué très attentivement exactement ce qu'il voulait dire par le mot «type», mais cela n'a pas aidé. Le mal était fait. "

"Mais il y a toujours une valeur énorme pour Apps hongrois, en ce sens qu'elle augmente la colocalisation dans le code, ce qui facilite la lecture, l'écriture, le débogage et la maintenance du code et, plus important encore, cela donne une mauvaise image du code."

Assurez-vous d'avoir un peu de temps avant de lire Joel On Software. :)

rlerallut
la source
Pas le temps maintenant que j'ai Stackoverflow. Je pense que la simple association de Spolsky avec le projet doit le faire. :)
Dustman
3

Plusieurs raisons:

  • N'importe quel IDE moderne vous donnera le type de variable en passant simplement votre souris sur la variable.
  • La plupart des noms de type sont très longs (pensez HttpClientRequestProvider ) pour être raisonnablement utilisés comme préfixe.
  • Les informations de type ne portent pas les bonnes informations, elles paraphrasent simplement la déclaration de variable, au lieu de décrire le but de la variable (pensez à myInteger vs pageSize ).
Joannes Vermorel
la source
2

Je ne pense pas que tout le monde y soit farouchement opposé. Dans les langages sans types statiques, c'est assez utile. Je la préfère définitivement lorsqu'elle est utilisée pour donner des informations qui ne sont pas déjà dans le type. Comme en C, char * szName dit que la variable fera référence à une chaîne terminée par null - ce qui n'est pas implicite dans char * - bien sûr, un typedef aiderait également.

Joel avait un excellent article sur l'utilisation du hongrois pour dire si une variable était encodée en HTML ou non:

http://www.joelonsoftware.com/articles/Wrong.html

Quoi qu'il en soit, j'ai tendance à ne pas aimer le hongrois lorsqu'il est utilisé pour transmettre des informations que je connais déjà.

Lou Franco
la source
Je pense que cette première phrase pourrait démentir les réponses sur cette page.
Dustman
@Dustman Eh bien, ne savez- vous pas déjà que les chaînes C sont terminées par null? Je vois à quel point ce serait utile quand la chaîne pourrait ne pas l'être, mais c'est rare et je pense donc que l'utilisation de la convention devrait être limitée à ces cas.
Plumenator
Tous les caractères * ne sont pas des chaînes c terminées par null. L'intérêt du hongrois est de l'utiliser pour chaque variable, même celles qui relèvent du cas commun. En fin de compte, je me sens comme vous - et donc je ne l'utilise pas en C.
Lou Franco
2

Bien sûr, lorsque 99% des programmeurs sont d'accord sur quelque chose, il y a quelque chose qui ne va pas. La raison pour laquelle ils sont d'accord ici est que la plupart d'entre eux n'ont jamais utilisé correctement la notation hongroise.

Pour un argumentaire détaillé, je vous renvoie à un article de blog que j'ai rédigé sur le sujet.

http://codingthriller.blogspot.com/2007/11/rediscovering-hungarian-notation.html

Greg
la source
2

J'ai commencé à coder à peu près à l'époque où la notation hongroise a été inventée et la première fois que j'ai été forcée de l'utiliser sur un projet, je l'ai détestée.

Après un certain temps, j'ai réalisé que quand c'était fait correctement, cela aidait et ces jours-ci j'adore ça.

Mais comme toutes les bonnes choses, il faut l'apprendre et le comprendre et le faire correctement prend du temps.

jussij
la source
1

La notation hongroise a été abusée, en particulier par Microsoft, conduisant à des préfixes plus longs que le nom de la variable, et montrant qu'elle est assez rigide, en particulier lorsque vous modifiez les types (le tristement célèbre lparam / wparam, de type / taille différent dans Win16, identique dans Win32 ).

Ainsi, à la fois en raison de cet abus et de son utilisation par M $, il a été jugé inutile.

À mon travail, nous codons en Java, mais le fondateur vient du monde MFC, alors utilisez un style de code similaire (accolades alignées, j'aime ça !, majuscules aux noms de méthodes, je suis habitué à cela, préfixe comme m_ aux membres de la classe (champs ), s_ aux membres statiques, etc.).

Et ils ont dit que toutes les variables devraient avoir un préfixe indiquant son type (par exemple, un BufferedReader est nommé brData). Ce qui est montré comme une mauvaise idée, car les types peuvent changer mais les noms ne suivent pas, ou les codeurs ne sont pas cohérents dans l'utilisation de ces préfixes (je vois même aBuffer, theProxy, etc.!).

Personnellement, j'ai choisi quelques préfixes que je trouve utiles, le plus important étant b pour préfixer les variables booléennes, car ce sont les seuls où j'autorise la syntaxe du genre if (bVar)(pas d'utilisation de la diffusion automatique de certaines valeurs à true ou false). Quand j'ai codé en C, j'ai utilisé un préfixe pour les variables allouées avec malloc, pour rappel il devrait être libéré plus tard. Etc.

Donc, fondamentalement, je ne rejette pas cette notation dans son ensemble, mais j'ai pris ce qui semble convenir à mes besoins.
Et bien sûr, lorsque je contribue à un projet (travail, open source), j'utilise juste les conventions en place!

PhiLho
la source