Jaka jest korzyść z niestosowania notacji węgierskiej?

101

Jedną z rzeczy, z którymi się zmagam, jest niestosowanie węgierskiej notacji. Ja nie chcę iść do definicji zmiennej po prostu zobaczyć, jakiego rodzaju jest. Kiedy projekt się rozrasta, miło jest móc patrzeć na zmienną poprzedzoną przez „bool” i wiedzieć, że szuka wartości prawda / fałsz zamiast wartości 0/1 .

Wykonuję również dużo pracy w SQL Server. Moje procedury składowane poprzedzam „sp”, a tabele „tbl”, nie wspominając o wszystkich moich zmiennych odpowiednio w bazie danych.

Wszędzie widzę, że nikt tak naprawdę nie chce używać węgierskiej notacji, do tego stopnia, że ​​tego unikają. Moje pytanie brzmi: jaka jest korzyść z niestosowania węgierskiej notacji i dlaczego większość programistów unika tego jak zarazy?

user29981
źródło
39
Jakiego języka / IDE używasz? W Visual Studio nie musisz przechodzić do definicji, aby poznać typ zmiennej, ponieważ IDE ci ją podaje. W językach, w których typy nie są wymuszane, takich jak PHP, nie musisz znać typu przez większość czasu (ponieważ możesz przypisać 0 lub 1 do wartości logicznej).
Arseni Mourzenko
10
@MainMa Nie jestem pewien, czy to dobry powód, aby nie znać typu wartości w PHP.
Rei Miyasaka,
29
„Kiedy projekty stają się obszerne” ... nie powinno mieć znaczenia. W dowolnym momencie powinna istnieć tylko niewielka liczba zmiennych: garść zmiennych klas i kolejna garść argumentów metod. Jeśli nie możesz utrzymać ich prosto, klasa jest za duża lub metoda jest za długa. Notacja węgierska została wymyślona do programowania w systemie Windows C, zasadniczo jako obejście strasznego interfejsu API systemu Windows. Nic podobnego nigdy nie było sugerowane ani pożądane przy opracowywaniu Uniksa.
kevin cline
20
jaka jest korzyść z niestosowania węgierskiego zapisu „Nie nienawidzić współpracowników” ...
Sean Patrick Floyd
25
adjHungarian nNotation vIs adjHard prepTo vRead.
dan04,

Odpowiedzi:

148

Ponieważ jego pierwotna intencja (patrz http://www.joelonsoftware.com/articles/Wrong.html i http://fplanque.net/Blog/devblog/2005/05/11/hungarian_notation_on_steroids ) została źle zrozumiana i została ( ab) używane, aby pomóc ludziom zapamiętać, jaki jest typ zmiennej, gdy używany przez nich język nie jest wpisany statycznie. W żadnym statycznie wpisanym języku nie potrzebujesz dodanego balastu przedrostków, aby powiedzieć ci, jaki jest typ zmiennej. W wielu nietypowych językach skryptowych może to pomóc, ale często nadużywano go do tego stopnia, że ​​stał się całkowicie nieporęczny. Niestety, zamiast wracać do pierwotnej intencji węgierskiej notacji, ludzie właśnie przeszli do jednej z tych „złych” rzeczy, których powinieneś unikać.

Krótko mówiąc, zapis węgierski miał poprzedzać zmienne pewną semantyką. Na przykład, jeśli masz współrzędne ekranu (lewy, górny, prawy, dolny), prefiksujemy zmienne o bezwzględnych pozycjach ekranu za pomocą „ abs”, a zmienne o pozycjach względem okna za pomocą „ rel”. W ten sposób byłoby oczywiste dla każdego czytelnika, gdy przekazałeś współrzędną względną do metody wymagającej pozycji bezwzględnych.

aktualizacja (w odpowiedzi na komentarz delnan)

IMHO nadużywanej wersji należy unikać jak zarazy, ponieważ:

  • komplikuje nazywanie. Gdy (ab) używa notacji węgierskiej, zawsze będą dyskusje na temat tego, jak szczegółowe powinny być prefiksy. Na przykład: listboxXYZlub MyParticularFlavourListBoxXYZ.
  • wydłuża nazwy zmiennych, nie pomagając zrozumieć, do czego służy zmienna.
  • w pewnym sensie pokonuje obiekt ćwiczenia, gdy w celu uniknięcia długich prefiksów skróca się je do skrótów i potrzebujesz słownika, aby wiedzieć, co oznacza każdy skrót. Czy uiliczba całkowita jest bez znaku? interfejs bez liczenia? coś wspólnego z interfejsami użytkownika? I te rzeczy mogą trwać długo . Widziałem prefiksy ponad 15 pozornie przypadkowych postaci, które mają przekazywać dokładny typ var, ale tak naprawdę tylko mistyfikować.
  • szybko się zużywa. Kiedy zmieniasz typ zmiennej, ludzie niezmiennie (lol) zapomnij zaktualizować prefiks, aby odzwierciedlić zmianę, lub celowo nie aktualizuj go, ponieważ spowodowałoby to zmiany kodu wszędzie tam, gdzie używany jest var ...
  • komplikuje mówienie o kodzie, ponieważ jako „@g”. powiedział: Nazwy zmienne z notacją węgierską są zwykle trudną do wymówienia zupą alfabetyczną. Utrudnia to czytelność i omawianie kodu, ponieważ nie można „powiedzieć” żadnej z nazw.
  • ... wiele innych rzeczy, których w tej chwili nie pamiętam. Może dlatego, że miałem przyjemność nie radzić sobie z nadużywaną notacją węgierską przez długi czas ...
Marjan Venema
źródło
9
@ Surfer513: Właściwie wolę sufiksy przy sterowaniu nazwami. Dla mnie o wiele bardziej interesujące jest znalezienie wszystkich kontrolek, które dotyczą określonego tematu / aspektu, niż znalezienie wszystkich kontrolek edycji ... Kiedy chcę znaleźć kontrolkę, w której użytkownik może wpisać nazwę klienta, zacznę szukać klient, a nie txt, ponieważ może to nie być txt (edycja), ale notatka, richedit lub ... Może nawet być polem kombi, które pozwala na znalezienie go we wcześniej wprowadzonych nazwach klientów ...
Marjan Venema
8
@ Surfer513: I obecnie używam sufiksów tylko przy rozróżnianiu dwóch kontrolek, które zajmują się tym samym. Na przykład etykieta i edycja nazwy klienta. I często sufiksy nie są związane z rodzajem kontroli, ale z jej celem: na przykład ClientCaption i ClientInput.
Marjan Venema
3
Warto również zauważyć, że intellisense w VS 2010 pozwala przeszukiwać całą nazwę, a nie tylko początek. Jeśli nazwiesz swoją kontrolkę „firstNameTextBox” i wpiszesz „textb”, znajdzie twoją kontrolę i wyświetli ją.
Adam Robinson
4
„... nadużywanej wersji unika się jak płytki nazębnej ...”, to znaczy unika się nieco mniej niż kamień nazębny i zapalenie dziąseł? ;-)
Ben Mosher
4
@Marjan: Oczywiście kompilator mógł to zauważyć. Jeśli każda jednostka jest reprezentowana przez typ, nie możesz przypadkowo przekazać jednej za drugą. Tutaj, jeśli masz a AbsoluteXTypei a RelativeYType, to nie możesz omyłkowo przekazać współrzędnej względnej Y dla absolutnej X. Wolę, aby zmienne reprezentujące niekompatybilne byty były niekompatybilnych typów, zamiast mieć niekompatybilne prefiksy. Kompilator nie dba o prefiksy (lub sufiksy).
Matthieu M.,
74

Notacja węgierska jest anty-wzorcem nazewnictwa we współczesnych środowiskach programistycznych i formie tautologii .

Bezużytecznie powtarza informacje bez korzyści i dodatkowych kosztów utrzymania. Co się stanie, gdy zmienisz swój inttyp na inny long, teraz musisz przeszukać i zastąpić całą bazę kodu, aby zmienić nazwy wszystkich zmiennych lub są one teraz semantycznie błędne, co jest gorsze, niż gdybyś nie powielił tego typu w nazwie.

To narusza zasadę SUCHEGO. Jeśli musisz poprzedzić tabele bazy danych skrótem, aby przypomnieć, że jest to tabela, to zdecydowanie nie nazywasz swoich tabel wystarczająco semantycznie opisowym. To samo dotyczy każdej innej rzeczy, z którą to robisz. To tylko dodatkowe pisanie i praca bez zysku lub korzyści w nowoczesnym środowisku programistycznym.

user7519
źródło
2
„Co się stanie, gdy zmienisz swój inttyp, na przykład long...” Proste: <sarkazm> Nie zmieniaj nazwy, ponieważ nie wiadomo, ile miejsc zmiana będzie falować. </sarkazm> Więc teraz masz zmienną, której Węgierska nazwa jest w konflikcie z jej implementacją. Nie ma absolutnie żadnego sposobu, aby powiedzieć, jak powszechne będą skutki zmiany nazwy, jeśli zmienna / funkcja będzie widoczna publicznie.
David Hammen
2
Powiązany artykuł jest fantastyczny i bardzo wart przeczytania. +1
Marty Pitt,
6
@David po prostu spójrz na Win32 API, który jest pełen zmiennych, parametrów, a nawet nazw metod, które przy użyciu notacji węgierskiej (co jest wymogiem w MS) wskazują wartość 8 lub 16 bitów, podczas gdy w rzeczywistości wszystkie były 32-bitowe wartości od czasu wprowadzenia systemu Windows 95 w 1994 r. (czyli prawie 17 lat temu).
jwenting
2
@Secure: Argumentowałbym, że to powinny robić automatyczne testy. Nie programiści.
Joel
2
@Secure może nie jest w wewnętrznej aplikacji, ale jeśli utrzymujesz publiczny interfejs API, taki jak Windows API, jest to poważny problem.
jwenting
51

Wikipedia ma listę zalet i wad notacji węgierskiej i dlatego może prawdopodobnie zapewnić najbardziej wyczerpującą odpowiedź na to pytanie. Znane opinie są również dość interesującą lekturą.

Korzyścią z niestosowania węgierskiej notacji jest w zasadzie jedynie uniknięcie jej wad:

  • Notacja węgierska jest zbędna, gdy kompilator dokonuje sprawdzania typu. Kompilatory dla języków zapewniające sprawdzanie typu zapewniają, że użycie zmiennej jest automatycznie zgodne z jej typem; kontrole wzrokowe są zbędne i podlegają błędom ludzkim.

  • Wszystkie nowoczesne zintegrowane środowiska programistyczne wyświetlają zmienne typy na żądanie i automatycznie oflagują operacje, które wykorzystują typy niezgodne, przez co notacja jest w dużej mierze przestarzała.

  • Notacja węgierska staje się myląca, gdy jest używana do reprezentowania kilku właściwości, takich jak a_crszkvc30LastNameCol: stały argument referencyjny, zawierający zawartość kolumny LastNametypu bazy danych, varchar(30)która jest częścią klucza podstawowego tabeli.

  • Może to prowadzić do niespójności, gdy kod zostanie zmodyfikowany lub przeniesiony. Jeśli typ zmiennej zostanie zmieniony, albo dekoracja nazwy zmiennej będzie niezgodna z nowym typem, albo nazwa zmiennej musi zostać zmieniona. Szczególnie dobrze znanym przykładem jest WPARAMtyp standardowy i towarzyszący mu wParamparametr formalny w wielu deklaracjach funkcji systemu Windows. „W” oznacza „słowo”, gdzie „słowo” jest rodzimym rozmiarem architektury sprzętowej platformy. Pierwotnie był to 16-bitowy typ w 16-bitowych architekturach słów, ale został zmieniony na 32-bitowy w 32-bitowych architekturach słów lub 64-bitowy w 64-bitowych architekturach słów w późniejszych wersjach systemu operacyjnego, zachowując jego oryginalna nazwa (jej prawdziwy typ bazowy toUINT_PTR, czyli liczba całkowita bez znaku, wystarczająco duża, aby pomieścić wskaźnik). Impedancja semantyczna, a co za tym idzie zamieszanie programistów i niespójność między platformami, zakłada, że ​​„w” oznacza 16-bit w różnych środowiskach.

  • Przez większość czasu znajomość użycia zmiennej oznacza znajomość jej typu. Ponadto, jeśli użycie zmiennej nie jest znane, nie można jej wywnioskować z jej typu.

  • Notacja węgierska znacznie zmniejsza korzyści płynące z używania bogatych w funkcje edytorów kodu, które obsługują uzupełnianie nazw zmiennych, ponieważ programista musi najpierw wprowadzić specyfikator całego typu.

  • Sprawia, że ​​kod jest mniej czytelny, zaciemniając cel zmiennej niepotrzebnymi prefiksami typu i zakresu.

  • Dodatkowe informacje o typie mogą niewystarczająco zastąpić bardziej opisowe nazwy. Np. sDatabaseNie mówi czytelnikowi, co to jest. databaseNamemoże być bardziej opisową nazwą.

  • Gdy nazwy są wystarczająco opisowe, dodatkowe informacje o typie mogą być zbędne. Np. firstNameNajprawdopodobniej jest łańcuchem. Tak więc nadanie mu nazwy sFirstNamedodaje bałaganu do kodu.

Ja sam nie używam tego zapisu, ponieważ nie lubię niepotrzebnego hałasu technicznego. Prawie zawsze wiem, z jakim typem mam do czynienia i chcę mieć czysty język w moim modelu domeny, ale piszę głównie w językach statycznych i silnie typowanych.

Falcon
źródło
1
To powinna być poprawna odpowiedź. To takie miłe. +1
Saeed Neamati
Jesteś zbyt miły, Saeed. Doceniam twoje uznanie, ale inne odpowiedzi na to pytanie też są naprawdę dobre.
Falcon
11
Głosowano za jednym zdaniem: „ Zazwyczaj znajomość użycia zmiennej oznacza znajomość jej typu. Ponadto, jeśli użycie zmiennej nie jest znane, nie można wywnioskować z jej typu. ” - IMHO, jest to pierwszy powód do unikania węgierskiej notacji.
Daniel Pryden
19

Jako problem specyficzny dla MS SQL Server:

Wszelkie procedury składowane z prefiksem „sp_” są najpierw wyszukiwane w głównej bazie danych, a nie w tej, w której zostały utworzone. Spowoduje to opóźnienie w wykonywaniu procedury przechowywanej.

tsundoku
źródło
4
+1 za bardzo fajne informacje. Używam „sp” jako mojego zapisanego prefiksu proc, a nie „sp_”. Niemniej jednak jest to zdecydowanie bardzo interesujący fakt i konkretny powód, aby nie używać „sp_” jako zapisanego prefiksu proc.
2
+1, nigdy tego nie wiedziałem, a kiedy zacząłem pracować na SQL Server, wszystkie SP w moim miejscu pracy były wcześniej oznaczone, sp_więc po prostu trzymałem się konwencji.
Michael
Świetna uwaga, ale nie ma nic wspólnego z tym pytaniem (Używanie sq a nie _sp). To tak, jakby pominąć nazwę schematu dla obiektów, które nie znajdują się w schemacie domyślnym.
JeffO
1
W przypadku procedur przechowywanych przez użytkownika konwencjonalnie użyłem „usp_”. Pozwoliło to uniknąć wspomnianego problemu ORAZ rozróżnić dla czytelnika, czy sproc był systemem, czy użytkownikiem.
Parasol
15

Największą korzyścią IMO z niestosowania węgierskiego jest to, że zmusza cię do używania znaczących nazw . Jeśli poprawnie nazywasz zmienne, powinieneś natychmiast wiedzieć, jaki to typ, lub być w stanie dość szybko wydedukować je w dobrze zaprojektowanym systemie. Jeśli trzeba polegać na strlub blnlub gorszy od wszystkich objprefiksów wiedzieć, jakiego typu jest zmienna, będę argumentować, oznacza to problem nazewnictwa - albo biednych nazw zmiennych w sposób ogólny lub zbyt ogólne, aby przekazać znaczenie.

Jak na ironię, z własnego doświadczenia wynika, że ​​głównym scenariuszem, w którym widziałem język węgierski, jest albo program „kultu ładunków” (tzn. Używa go inny kod, więc używajmy go tylko dlatego, że tak się dzieje) lub w VB.NET, aby obejść ten fakt rozróżnianie wielkości liter (np. Person oPerson = new Personponieważ nie można użyć Person person = new Personi Person p = new Personjest zbyt niejasne); W tym przypadku widziałem też prefiks „the” lub „my” (jak w Person thePerson = new Personlub brzydsze Person myPerson = new Person).

Dodam, że jedyny raz, kiedy używam węgierskiego, jest formant ASP.NET i to jest naprawdę kwestia wyboru. Uważam, że pisanie TextBoxCustomerNamelub CustomerNameTextBoxprostsze jest bardzo brzydkie txtCustomerName, ale nawet to wydaje się „brudne”. Wydaje mi się, że do kontroli należy zastosować jakąś konwencję nazewnictwa, ponieważ może istnieć wiele formantów wyświetlających te same dane.

Wayne M.
źródło
13

Skoncentruję się na SQL Server, odkąd o nim wspomniałeś. Nie widzę powodu, aby umieszczać „tbl” przed stołem. Możesz po prostu spojrzeć na dowolny kod tSQL i rozróżnić tabelę według sposobu jego użycia. Nigdy nie Select from stored_procedure.lub nie Select from table(with_param)chcesz UDF lub Execute tblTableOrViewNamejak procedura składowana.

Tabele można pomylić z widokiem, ale jeśli chodzi o sposób ich użycia; nie ma różnicy, więc o co chodzi? Notacja węgierska może zaoszczędzić czas na wyszukiwanie w SSMS (pod tabelą lub widokami?), Ale o to chodzi.

Zmienne mogą stanowić problem, ale należy je zadeklarować i jak daleko od instrukcji deklaracji zamierzasz używać zmiennej? Przewijanie kilku wierszy nie powinno być wielkim problemem, chyba że piszesz bardzo długie procedury. Dobrym pomysłem może być trochę rozbicie długiego kodu.

Opisujesz ból, ale rozwiązanie węgierskiej notacji tak naprawdę nie rozwiązuje problemu. Możesz spojrzeć na kod innej osoby i stwierdzić, że typ zmiennej może ulec zmianie, co wymaga teraz zmiany nazwy zmiennej. Jeszcze tylko jedna rzecz do zapomnienia. A jeśli użyję VarChar, i tak będziesz musiał spojrzeć na instrukcję deklaracji, aby poznać rozmiar. Nazwy opisowe zapewne doprowadzą cię dalej. @PayPeriodStartDate prawie się wyjaśnia.

JeffO
źródło
2
@ Surfer: Klucz podstawowy jest inny, ponieważ „PK” nie jest tego typu; „PK_TableName” mówi „to jest klucz podstawowy dla TableName”, a nie „to TableName typu PK”. Co do reszty ... to nie brzmi, jakbyś naprawdę słuchał argumentów tutaj. Przestańcie stosować tę obrzydliwą praktykę, która do dziś upiera się nad obniżeniem zbiorowej jakości całego kodu.
Aaronaught
2
@Aaronaught, określasz jeden aspekt notacji węgierskiej ( en.wikipedia.org/wiki/Hungarian_notation ). To nie tylko typ, ale także przeznaczenie. Tak więc prefiks „pk” dla klucza podstawowego jest w rzeczywistości notacją węgierską. Słucham tutaj argumentów, ale są wyjątki (takie jak sytuacja z kluczem podstawowym), w których wydaje się, że HN jest korzystny. Może, może nie. Nadal staram się owijać głowę wokół nakazów i zakazów we wszystkich scenariuszach. Dowiedziałem się dzisiaj sporo na ten temat i wywołałem świetną myśl.
3
@ Surfer: To po prostu nieprawda. Notacja węgierska opisuje albo typ (zła wersja), albo konkretne użycie typu (mniej zła wersja). PK nie jest, nie tylko opisuje coś o typie, ale opisuje zachowanie . Kiedy mówię o, powiedzmy, wieku, jest to całkowicie nieciekawe, że jest to liczba całkowita, ale kiedy mówię o ograniczeniu bazy danych, „klucz podstawowy dla tabeli X” jest dokładnie ważny.
Aaronaught
4
Podoba mi się twój drugi do ostatniego akapitu. Uzasadnieniem mojej firmy do używania notacji węgierskiej jest: „Pozwala nam szybko zobaczyć, które zmienne są globalne, a które nie”. A potem patrzysz na deklaracje zmiennych i jest 300 zmiennych na plik, niektóre m * dla modularnego (globalnego), niektóre v * dla lokalnego NAWET MYŚL OZNACZAJĄ NA POZIOMIE MODUŁOWYM. „Och, to dlatego, że są przeznaczone wyłącznie do użytku lokalnego, a nie modułowego”. facepalm
corsiKa
3
@Aaronaught: W moim bieżącym projekcie używamy nazw tabel z prefiksem tbl_ . Chociaż nie jestem wielkim fanem tej praktyki, nie rozumiem, jak to „obniża zbiorową jakość całego kodu” . Czy możesz podać przykład?
Treb
6

Inną rzeczą do dodania jest to, jakich skrótów użyłbyś dla całego frameworku, takiego jak .NET? Tak, tak łatwo jest pamiętać, że btnreprezentuje przycisk i txtreprezentuje pole tekstowe. Co jednak masz na myśli StringBuilder? strbld? Co CompositeWebControl? Czy używasz czegoś takiego:

CompositeWebControl comWCMyControl = new CompositeWebControl();

Jedną z nieefektywności węgierskiej notacji było to, że posiadając coraz większe frameworki, okazało się nie tylko nieść dodatkowe korzyści, ale także zwiększyć złożoność dla programistów, ponieważ musieli oni teraz coraz częściej uczyć się niestandardowych prefiksów.

Saeed Neamati
źródło
6

Według mojego spojrzenia na sprawy, notacja węgierska stanowi kłopot dla obejścia niewystarczająco wydajnego systemu pisma. W językach, które pozwalają definiować własne typy, tworzenie nowego typu, który koduje oczekiwane zachowanie, jest stosunkowo proste. W tekście Joela Spolsky'ego dotyczącym notacji węgierskiej podaje przykład wykorzystania go do wykrywania możliwych ataków XSS, wskazując, że zmienna lub funkcja jest albo niebezpieczna (my), albo bezpieczna (e), ale to wciąż programista musi sprawdzić wizualnie. Jeśli zamiast tego masz rozszerzalny system typów, możesz po prostu utworzyć dwa nowe typy, UnsafeString i SafeString, a następnie użyć ich odpowiednio. Jako bonus typ kodowania staje się:

SafeString encode(UnsafeString)

i brak dostępu do wewnętrznych elementów UnsafeString lub korzystanie z innych funkcji konwersji staje się jedynym sposobem na przejście z UnsafeString do SafeString. Jeśli wszystkie funkcje wyjściowe biorą tylko instancje SafeString, niemożliwe jest wyprowadzenie ciągów, które nie są znakami ucieczki [wykluczając shenanigany za pomocą konwersji takich jak StringToSafeString (someUnsafeString.ToString ())].

Powinno być oczywiste, dlaczego pozwolenie systemowi poczytalności na sprawdzenie poprawności kodu jest lepsze niż próba zrobienia tego ręcznie, a może w tym przypadku oko.

W języku, takim jak C, oczywiście wkręca cię to, że int jest int jest int, i nie możesz na to wiele poradzić. Zawsze możesz grać w gry ze strukturami, ale można się zastanawiać, czy to poprawa, czy nie.

Co do innej interpretacji notacji węgierskiej, prefiks IE z typem zmiennej, jest to po prostu głupie i zachęca do leniwych praktyk, takich jak nazywanie zmiennych uivxwFoo zamiast czegoś znaczącego, takiego jak countOfPeople.

Orclev
źródło
Jak zadeklarować typ .NET lub Java, aby opisać „ int[]które mogą być dowolnie modyfikowane, ale nigdy nie mogą być udostępniane” lub „ int[]które mogą być swobodnie udostępniane tylko między rzeczami, które nigdy go nie modyfikują”? Jeśli int[]pole foozawiera wartości, to czy {1,2,3}można je kapsułkować, {2,2,3}nie wiedząc, który „typ” int[]reprezentuje? Sądzę, że Java i .NET byłyby znacznie lepsze, gdyby - przy braku obsługi systemu typów, przyjęły przynajmniej konwencję nazewnictwa w celu rozróżnienia tych typów.
supercat
4

Notacja węgierska jest prawie całkowicie bezużyteczna w języku pisanym statycznie. Jest to podstawowa funkcja IDE, która pokazuje typ zmiennej poprzez umieszczenie myszy nad nią lub w inny sposób; ponadto możesz zobaczyć, jaki jest typ, patrząc na kilka linii w górę tam, gdzie został zadeklarowany, jeśli nie ma wnioskowania o typie. Istotą wnioskowania o typie jest nie powtarzanie wszędzie takiego szumu, więc węgierska notacja jest zwykle postrzegana jako zła rzecz w językach z wnioskowaniem o typie.

W dynamicznie wpisywanych językach czasem może to pomóc, ale dla mnie wydaje się jednoznaczne. Już zrezygnowałeś z funkcji ograniczonych do dokładnych domen / kodomains; jeśli wszystkie twoje zmienne są nazwane węgierską notacją, to po prostu odtwarzasz to, co dałby ci system typów. Jak wyrazić zmienną polimorficzną, która może być liczbą całkowitą lub łańcuchem w notacji węgierskiej? „IntStringX”? „IntOrStringX”? Jedynym miejscem, w którym kiedykolwiek używałem węgierskiej notacji, był kod asemblera, ponieważ próbowałem odzyskać to, co dostanę, gdybym miał system pisma, i to była pierwsza rzecz, jaką kodowałem.

Tak czy inaczej, nie obchodzi mnie, jak ludzie nazywają swoje zmienne, kod prawdopodobnie nadal będzie tak samo niezrozumiały. Programiści marnują zbyt wiele czasu na takie rzeczy, jak styl i nazwy zmiennych, a pod koniec dnia wciąż masz mnóstwo bibliotek z zupełnie innymi konwencjami w Twoim języku. Rozwijam język symboliczny (tj. Nietekstowy), w którym nie ma nazw zmiennych, tylko unikalne identyfikatory i sugerowane nazwy zmiennych (ale większość zmiennych wciąż nie ma sugerowanych nazw, ponieważ po prostu nie istnieje rozsądna nazwa dla im); podczas kontroli niezaufanego kodu nie można polegać na nazwach zmiennych.

Longpoke
źródło
Jest również całkiem bezużyteczny dla większości dynamicznie pisanych języków!
James Anderson
2
w przypadku IDE jest nawet gorzej niż w przypadku ręcznego kodowania, ponieważ oznacza to, że uzupełnianie kodu jest znacznie spowolnione. Jeśli masz 100 zmiennych całkowitych, wpisanie int <przestrzeń-przestrzeni> (na przykład) powoduje wyświetlenie 100 pozycji do przewinięcia. Jeśli potrzebna jest intVeryLongVariableName, uzupełnianie kodu staje się problematyczne. Bez węgierskiego wpisujesz po prostu bardzo <alt-space> i masz tylko 1 lub 2 opcje.
jwenting
3

Jak zwykle w takim przypadku, opublikuję odpowiedź, zanim przeczytam odpowiedzi od innych uczestników. 

Widzę trzy „błędy” w twojej wizji: 

1) Jeśli chcesz poznać typ zmiennej / parametru / atrybutu / kolumny, możesz najechać myszą lub kliknąć ją, a zostanie wyświetlona w najnowocześniejszym IDE. Nie wiem, jakich narzędzi używasz, ale ostatnim razem byłem zmuszony do pracy w środowisku, które nie zapewniało tej funkcji, w XX wieku, językiem był COBOL, oops nie, to był Fortran, a mój szef nie rozumiem, dlaczego odszedłem. 

2 / Rodzaje mogą ulec zmianie w trakcie cyklu rozwoju. 32-bitowa liczba całkowita może w pewnym momencie stać się 64-bitową liczbą całkowitą, z dobrych powodów, których nie wykryto na początku projektu. Tak więc zmiana nazwy intX na longX lub pozostawienie go z nazwą wskazującą na niewłaściwy typ to zła karma. 

3) To, o co prosisz, to w rzeczywistości redundancja. Redundancja nie jest dobrym wzorcem projektowym ani nawykiem. Nawet ludzie są niechętni zbytniej redundancji. Nawet ludzie są niechętni zbytniej redundancji. 

Oqaqiq
źródło
Rozumiem zaawansowane / nowoczesne IDE i całkowicie się z tobą zgadzam. Ale co z projektem bazy danych? Załóżmy, że masz kolumnę lub parametr procedury składowanej. Najechanie kursorem na lewę tak naprawdę nie działa z tego rodzaju rzeczami. Musisz spojrzeć na definicję tabeli / przechowywanego proc. Co ty na to robisz?
3

Uważam, że bycie w potrzebie węgierskiego jest objawem .
Objaw zbyt wielu zmiennych globalnych ... lub zbyt długich funkcji, aby można je było utrzymać .

Jeśli Twoja definicja zmiennej nie jest widoczna, zazwyczaj masz problemy.
A jeśli twoje funkcje nie są zgodne z niezapomnianą konwencją , to znowu, duży problem.

To ... to chyba powód, dla którego wiele miejsc pracy tak go wyśmiewa.

Pochodzi z języków, które tego potrzebowały .
W czasach globalnych zmiennych bonanza . (z braku alternatyw)
Dobrze nam to służyło.

Jedynym prawdziwym użycie mamy za to dzisiaj jest Joel Spolsky jeden .
Aby śledzić niektóre szczególne atrybuty zmiennej, takie jak jej bezpieczeństwo .

( np. „Czy zmienna safeFoobarma zielone światło, które należy wprowadzić do zapytania SQL?
- Jak się nazywa safe, tak”)

Niektóre inne odpowiedzi mówiły o funkcjach edytora, które pomogły zobaczyć typ zmiennej podczas najechania na nią. Moim zdaniem, one również stanowią pewien problem dla bezpieczeństwa kodu . Uważam, że były one przeznaczone tylko do refaktoryzacji , podobnie jak wiele innych funkcji (takich jak składanie funkcji) i nie powinny być używane w nowym kodzie.

ZJR
źródło
2

Myślę, że powody, dla których nie używano węgierskiej notacji, zostały dobrze omówione przez inne plakaty. Zgadzam się z ich komentarzami.

W bazach danych używam notacji węgierskiej dla obiektów DDL, które rzadko są używane w kodzie, ale w przeciwnym razie kolidowałyby w przestrzeniach nazw. Głównie sprowadza się to do prefiksowania indeksów i nazwanych ograniczeń ich typem (PK, UK, FK i IN). Użyj spójnej metody, aby nazwać te obiekty, a powinieneś być w stanie uruchomić sprawdzanie poprawności poprzez zapytanie do metadanych.

BillThor
źródło
Często zdarza mi się tak, gdy mam tabelę identyfikatorów. Gdybym miał TABLE SomeStringById(int somestringId, varchar somestring)indeks, logicznie byłoby, SomeStringByIdale to powoduje kolizję. Więc to nazywam idx_SomeStringById. Następnie, aby pójść w ich ślady, zrobię to idx_SomeStringByValuetylko dlatego, że głupotą jest mieć idx_jedną z nich, a nie drugą.
corsiKa
1

powodem tego jest to, że system węgierski narusza DRY (prefiks jest dokładnie tym typem, który może uzyskać kompilator i (dobre) IDE)

aplikacje węgierskie prefiksy OTOH za pomocą zmiennej (tj. scrxMouse jest współrzędną topora na ekranie może to być int, krótki, długi lub nawet niestandardowy typ (typedefs pozwoli nawet łatwo to zmienić))

nieporozumienie systemów zniszczyło węgierski kraj jako najlepszą praktykę

maniak zapadkowy
źródło
2
Nie mogę się zgodzić - tym, co zniszczyło węgierski jako „najlepszą praktykę”, jest to, że nigdy nie był on bliski najlepszej (lub nawet dobrej) praktyce.
Jerry Coffin
2
@haylem: Widziałem artykuły i oryginalny artykuł Simonyi i przeczytałem kod. Pod każdym względem, gdy na to spojrzysz, to zły pomysł, który nigdy nie powinien ujrzeć światła dziennego.
Jerry Coffin
1
Nie musi to naruszać DRY w dynamicznym języku; to po prostu unidiomatic. SUSZENIE niekoniecznie zawsze jest dobre; np .: makra C.
Longpoke,
3
IMO co „zniszczone” węgierski jest fakt, że nawet „zamiar” nie jest użyteczne w porównaniu z użyciem nazw opisowych , choć aby być uczciwym, kiedy węgierski powstał tam nie był to ruch za posiadanie kodu czytelnego ...
Wayne Molina
1
@Wayne M: „opisowe nazwy” łatwo powiedzieć, kiedy kompilatory zasadniczo pozwalają na użycie eseju dla nazwy zmiennej. Kiedy długość nazw identyfikatorów była faktycznie ograniczona do niskiej, dość arbitralnej wartości (myślę, że wspólny limit wynosił osiem lub dziesięć znaków jeszcze nie tak dawno temu; wydaje mi się, że Borland Turbo C 2 miał nawet opcję konfiguracji dla maksymalna długość nazwy identyfikatora!), kodowanie przydatnych informacji w nazwie było tylko trochę trudniejsze ...
CVn
1

Powiedzmy, że mamy taką metodę (w C #):

int GetCustomerCount()
{
    // some code
}

Teraz w kodzie nazywamy to tak:

var intStuff = GetCustomerCount();
// lots of code that culminates in adding a customer
intStuff++;

Int nie mówi nam bardzo wiele. Sam fakt, że coś jest intem, nie mówi nam, co w tym jest. Załóżmy teraz, że nazywamy to tak:

var customerCount = GetCustomerCount();
// lots of code that culminates in adding a customer
customerCount++;

Teraz możemy zobaczyć, jaki jest cel zmiennej. Czy miałoby to znaczenie, gdybyśmy wiedzieli, że to int?

Pierwotnym celem Węgier było jednak zrobienie czegoś takiego:

var cCustomers = GetCustomerCount();
// lots of code that culminates in adding a customer
cCustomers++;

Jest to w porządku, o ile wiesz, co oznacza c . Ale musiałbyś mieć standardową tabelę prefiksów i wszyscy musieliby je znać, a każda nowa osoba musiałaby się ich nauczyć, aby zrozumieć Twój kod. Natomiast customerCountlub countOfCustomersjest dość oczywiste na pierwszy rzut oka.

Węgierski miał jakiś cel w VB, zanim Option Strict Onistniał, ponieważ w VB6 i wcześniejszych (i w VB .NET z Option Strict Off) VB wymuszałoby typy, więc możesz to zrobić:

Dim someText As String = "5"
customerCount = customerCount + someText

To źle, ale kompilator by tego nie powiedział. Więc jeśli użyjesz węgierskiego, przynajmniej będziesz miał pewien wskaźnik tego, co się dzieje:

Dim strSomeText As String = "5"
intCustomerCount = intCustomerCount + strSomeText  // that doesn't look right!

W .NET, przy wpisywaniu statycznym, nie jest to konieczne. A węgierski był zbyt często używany jako substytut dobrego imienia. Zapomnij o węgierskim i wybierz dobre imię.

Kyralessa
źródło
1

Znalazłem wiele dobrych argumentów przeciwko, ale jednego nie widziałem: ergonomii.

W dawnych czasach, gdy wszystko, co miałeś, to string, int, bool i float, znaki sibf byłyby wystarczające. Ale z łańcuchem + krótkim zaczynają się problemy. Użyć całej nazwy dla prefiksu lub str_name dla ciągu? (Chociaż nazwy są prawie zawsze ciągami - prawda?) Co jest z klasą Street? Nazwy stają się coraz dłuższe i nawet jeśli używasz CamelCase, trudno jest powiedzieć, gdzie kończy się prefiks typu i gdzie zaczyna się nazwa zmiennej.

 BorderLayout boderLayoutInnerPanel = new BorderLayout ();
 panelInner.addLayout (borderLayoutInnerPanel);

Okej - możesz użyć podkreśleń, jeśli nie używasz ich już do czegoś innego, lub użyć CamelCase, jeśli używasz podkreśleń tak długo:

 BorderLayout boderLayout_innerPanel = new BorderLayout ();
 panel_inner.addLayout (borderLayout_innerPanel);

 Border_layout boder_layoutInner_panel = new Border_layout ();
 panelInner.add_layout (border_layoutInner_panel);

To potworne, a jeśli zrobisz to konsekwentnie, będziesz miał

 for (int iI = 0; iI < iMax-1; ++iI)
     for (int iJ = iI; iJ < iMax; ++iMax) 
          int iCount += foo (iI, iJ); 

Albo skończysz na używaniu bezużytecznych prefiksów w trywialnych przypadkach, takich jak zmienne pętlowe lub count. Kiedy ostatnio używałeś krótkiego lub długiego licznika? Jeśli robisz wyjątki, często tracisz czas, myśląc o potrzebie prefiksu, czy nie.

Jeśli masz wiele zmiennych, zwykle są one pogrupowane w przeglądarce obiektów, która jest częścią twojego IDE. Teraz, jeśli 40% zaczyna się od i_ dla int, a 40% z s_ dla string, a są one posortowane alfabetycznie, trudno jest znaleźć znaczną część nazwy.

nieznany użytkownik
źródło
1

Jedynym miejscem, w którym wciąż regularnie używam węgierskich lub analogicznych sufiksów, są konteksty, w których te same dane semantyczne występują w dwóch różnych formach, takich jak konwersja danych. Może się tak zdarzyć w przypadkach, gdy istnieje wiele jednostek miary lub istnieje wiele form (np. Ciąg „123” i liczba całkowita 123).

Uważam, że podane tutaj powody, dla których nie używałem tego języka, nie zachęcają innych do narzucania węgierskiego, ale są jedynie lekko sugestywne, aby decydować o własnej praktyce.

Kod źródłowy programu jest sam w sobie interfejsem użytkownika - wyświetla algorytmom i metadanym opiekunowi - a nadmiarowość interfejsów użytkownika jest zaletą, a nie grzechem . Zobacz np. Zdjęcia w „ The Design of Everyday Things ” i spójrz na drzwi z napisem „Push”, które wyglądają, jakbyś je pociągnął, a na krany piwa operatorzy włamali się na ważne elementy sterowania reaktora jądrowego, ponieważ „unosiły się nad nim” w IDE ”nie było wystarczająco dobre.

„Po prostu najechanie na IDE” nie jest powodem, aby nie używać węgierskiego - tylko powodem, dla którego niektórzy ludzie mogą nie uznać go za użyteczny. Twój przebieg może się różnić.

Pomysł, że Węgier nakłada znaczne obciążenia konserwacyjne, gdy zmiana typów zmiennych jest głupi - jak często zmieniasz typy zmiennych? Poza tym zmiana nazw zmiennych jest łatwa:

Wystarczy użyć IDE, aby zmienić nazwę wszystkich wystąpień. -Gander, odpowiadając na Goose

Jeśli język węgierski naprawdę pomaga szybko odczytać fragment kodu i niezawodnie go zachować, użyj go. Jeśli nie, nie rób tego. Jeśli inni powiedzą ci, że mylisz się co do własnych doświadczeń, sugeruję, że to oni prawdopodobnie są w błędzie.

Ed Staub
źródło