Чи є угорська позначення способом вирішення для мов із недостатньо вираженою статичною типізацією? [зачинено]


28

У статті Еріка Ліпперта Що відбувається з угорською нотацією? , він заявляє, що метою угорської нотації (доброго роду) є

розширити поняття "тип", щоб охопити смислову інформацію на додаток до інформації про представлення на зберігання.

Простим прикладом може бути префіксація змінної, яка представляє координату X з "x" та змінну, яка представляє Y-координату з "y", незалежно від того, чи є ці змінні цілими чи плаваючими чи будь-якими іншими, так що, коли ви випадково пишете xFoo + yBar, код явно виглядає неправильно.

Але я також читав про систему типів Haskell, і, схоже, в Haskell можна зробити те саме (тобто "розширити поняття типу, щоб охопити смислову інформацію"), використовуючи фактичні типи, які компілятор перевірить для вас. Так, у наведеному вище прикладі, xFoo + yBarв Haskell насправді не вдалося б компілювати, якщо ви правильно спроектували свою програму, оскільки вони будуть оголошені як несумісні типи. Іншими словами, схоже, що система типу Haskell ефективно підтримує перевірку часу компіляції, еквівалентну угорській нотації

Отже, чи угорська нотація є лише смугою допомоги для мов програмування, системи типу яких не можуть кодувати семантичну інформацію? Або Угорська нотація пропонує щось поза тим, що може запропонувати система статичного типу, така як Haskell?

(Звичайно, я використовую Haskell в якості прикладу. Я впевнений, що існують інші мови з подібними експресивними (багатими? Сильними?) Системами типу, хоча я не зустрічав жодної.)


Щоб було зрозуміло, я не говорю про анотування імен змінних з типом даних , а про інформацію про значення змінної в контексті програми. Наприклад, змінна може бути цілим чи поплавковим чи подвійним чи довгим чи будь-яким іншим, але, можливо, сенс змінної полягає в тому, що це відносна x-координата, виміряна в дюймах. Це така інформація, яку я говорю про кодування за допомогою угорської нотації (і через типи Haskell).


Pascal - хоча якщо ви спробуєте додати тип XCood та YCoord, визначений у Pascal, ви просто отримаєте попередження про компілятор IIRC
mcottle

1
blog.moertel.com/articles/2006/10/18/… - це стаття про те, як зробити щось дуже схоже на "угорські програми" в системі типів у Haskell.
Логан Капальдо

1
F # має таку особливість стилю.
Рангорік

Це дійсно приємне посилання на статтю (Moertel.com), що показує саме те, про що я думав: використання системи типів для перетворення вразливих місць безпеки між інтерполяцією та подібних у помилки компіляції. Дякуємо за посилання
Райан К. Томпсон

Думаю, багато що OO наздогнали угорські позначення семантики, тому що сьогодні ви, напевно, напишете: Foo.Position.X + Bar.Position.Y.
Пітер Б

Відповіді:


27

Я б сказав "Так".

Як ви кажете, мета Угорської нотації - це кодувати інформацію в імені, яке не може бути закодовано у типі. Однак в основному є два випадки:

  1. Ця інформація важлива.
  2. Ця інформація не важлива.

Почнемо спочатку зі випадку 2: якщо ця інформація не є важливою, тоді Угорська нотація - просто зайвий шум.

Більш цікавий випадок - номер 1, але я заперечую, що якщо інформація важлива, її слід перевірити, тобто вона повинна бути частиною типу , а не назвою .

Що повертає нас до цитату Еріка Ліпперта:

розширити поняття "тип", щоб охопити смислову інформацію на додаток до інформації про представлення на зберігання.

Власне, це не "розширення поняття типу", це поняття типу! Вся метою типів (як інструмент проектування) є кодування семантичної інформації! Подання зберігання є деталлю реалізації , яка зазвичай не відноситься до типу на всіх . (А конкретніше, мова мови OO не може належати до цього типу, оскільки незалежність представництва є однією з головних передумов OO.)


C, де угорські позначення були найчастіше використовуваними AFAIK, не є мовою ОО.
Péter Török

4
@ PéterTörök: OO - це модель дизайну, а не особливість мови, хоча сучасні мови створені для того, щоб зробити це легше, а C - ні.
Ян Худек

3
@ PéterTörök: Я написав досить багато об'єктно-орієнтованого коду в простому С. Я знаю, про що я говорю.
Ян Худек

1
Хоча може бути правдою, що важлива інформація повинна бути вбудована у тип змінної, а не її ім'я, є багато важливих речей, про які слід сказати, але які типи систем не можуть висловити. Наприклад, якщо S1це єдине посилання в будь-якій точці Всесвіту на того char[], чий власник може і буде змінювати його коли завгодно, але ніколи не повинен піддаватися зовнішньому коду, і S2є посиланням на char[]яке ніхто ніколи не повинен змінюватись, але яке може бути спільним з предметами, які обіцяють не змінювати його, S1чи S2слід розцінювати семантично як одну і ту ж «річ»?
суперкат

1
@supercat - Ви описуєте унікальні типи.
Джек

9

Вся мета типів (як інструмент дизайну) - кодувати смислову інформацію!

Мені сподобалась ця відповідь і я хотів продовжити цю відповідь ...

Я нічого не знаю про Haskell, але ви можете виконати щось на зразок прикладу xFoo + yBarбудь-якою мовою, яка підтримує певну форму безпеки типу, наприклад, C, C ++ або Java. У C ++ ви можете визначити класи XDir і YDir з перевантаженими операторами '+', які приймають лише об'єкти власного типу. В C або Java вам потрібно буде зробити додавання, використовуючи функцію / метод add () замість оператора "+".

Я завжди бачив угорські позначення, які використовуються для інформації про тип, а не для семантики (за винятком випадків, коли семантика може бути представлена ​​типом). Зручний спосіб запам'ятати тип змінної ще за дні до "розумних" редакторів програмування, які відображають тип для вас так чи інакше прямо в редакторі.


Орієнтованість на об'єкти не є ні необхідною, ні достатньою для того, щоб мова давала змогу xFoo + yBarвизначати визначені користувачем типи, а також для цього прикладу OO аспект C ++ не потрібен.
Люк Дантон

Ви маєте рацію, це не ОО, це безпека типу. Я відредагував свою відповідь.
BHS

Хм. Це добре, що ви можете зробити xFoo + yBarпомилку компіляції (або принаймні помилку виконання) майже на будь-якій мові. Однак чи буде математика з класами XDir та YDir у, скажімо, Java чи C ++ повільнішою, ніж математика із необробленими числами? Я розумію, що в Haskell типи перевіряються під час компіляції, а потім під час виконання, це буде просто необроблена математика без перевірки типу, а отже, не повільніше, ніж додавання звичайних чисел.
Райан К. Томпсон

У C ++ перевірка типу також проводитиметься під час компіляції, а перетворення та таке в більшості випадків буде оптимізовано. Java також не робить це, тому що не дозволяє перезавантажувати оператора і таке подібне - тому, наприклад, ви не можете ставитися до XCoordinateзвичайного int.
cHao

5

Я розумію, що фраза "Угорська нотація" означала щось інше, ніж оригінал , але я відповім "ні" на питання. Іменування змінних або семантичного, або обчислювального типу не робить те саме, що введення стилю SML або Haskell. Це навіть не пов'язка. Взявши за приклад C, ви можете назвати змінну gpszTitle, але ця змінна може не мати глобальної сфери застосування, вона навіть не може вказувати на нульовий завершений рядок.

Я думаю, що більш сучасні угорські позначення мають ще більшу відмінність від системи дедукції сильного типу, оскільки вони поєднують "семантичну" інформацію (наприклад, "g" для глобальної чи "f" для прапора) з обчислювальним типом ("p" покажчик ", Я "ціле число, і т. д. і т. д.) Це просто закінчується непристойним безладом, коли імена змінних мають лише невиразну схожість з їхнім обчислювальним типом (який змінюється з часом) і всі виглядають настільки подібними, що не можна використовувати" наступний матч "для знайти змінну в певній функції - вони всі однакові.


4

Угорська нотація була винайдена для BCPL, мови, яка взагалі не мала типів. А точніше, він мав рівно один тип даних, це слово. Слово може бути вказівником, або це може бути символом, булевим чи простим цілим числом, залежно від того, як ви його використовували. Очевидно, це дозволило дуже легко робити жахливі помилки, такі як перенаправлення персонажа. Таким чином, угорська нотація була винайдена, щоб програміст міг хоча б виконати ручну перевірку типу, подивившись на код.

C, нащадок BCPL, має різні типи для цілих чисел, покажчиків, символів тощо. Це зробило базову позначку угорської мови в певній мірі зайвою (вам не потрібно було кодувати ім'я змінної, якщо це було int чи покажчик), але семантика поза цим рівнем все ще не може бути виражена як типи. Це призводить до розмежування того, що було названо "Системи" та "Програми" угорською. Вам не потрібно було виражати, що змінна - це int, але ви можете використовувати кодові букви, щоб вказати, чи є int координатою x, y або індексом.

Більш сучасні мови дозволяють визначити власні типи, а це означає, що ви можете кодувати смислові обмеження у типах, а не в назвах змінних. Наприклад, типова мова OO матиме конкретні типи для пар координат та областей, тож ви уникаєте додавання координати x до координати y.

Наприклад, у відомій статті Joels, що вихваляє Apps Hungarian, він використовує приклад префікса usдля небезпечної рядки та sдля безпечної (HTML-кодованої) рядки, щоб запобігти введенню HTML. Розробник може запобігти помилкам введення HTML, просто уважно перевіривши код і переконайтеся, що змінні префікси збігаються. Його приклад - у VBScript, тепер застарілій мові, яка спочатку не дозволяла користувацьким класам. Сучасною мовою проблему можна вирішити за допомогою користувацького типу, і це саме те, що робить Asp.net з HtmlStringкласом. Таким чином компілятор автоматично знайде помилку, що набагато безпечніше, ніж покладатися на людське очне яблуко. Тож чітко мова з користувацькими типами позбавляє від необхідності "Угорської програми".


2

Так, хоча у багатьох мов, які мають інакше достатньо сильні системи типів, все ще виникає проблема - виразність нових типів, що базуються на / схожі на існуючі типи.

тобто в багатьох мовах, де ми могли б більше використовувати типову систему, ми цього не робимо, оскільки накладні витрати на створення нового типу, який в основному такий же, як існуючий тип, відмінний від імені, і пара функцій перетворення занадто великий.

По суті, нам потрібні якісь сильно набрані typedefs, щоб повністю знищити угорські позначення на цих мовах (U # стиль UoM також міг би це зробити)


2

Пам’ятайте, був час, коли у IDE не було підказки, що розповідає про те, що таке тип змінної. Був час, коли IDE не розуміли код, який вони редагували, тому ви не могли легко перейти від використання до декларації. Був також час, коли ви не змогли перефактурувати ім’я змінної, не вручну пройшовши всю кодову базу, внісши зміни вручну і сподіваючись, що ви її не пропустите. Ви не можете використовувати пошук і заміну, оскільки пошук Клієнта також отримує Ім'я клієнта ...

Ще в ті темні дні було корисно дізнатися, який тип змінної був там, де вона використовується. Якщо належним чином підтримується (БОЛЬШОГО, якщо через відсутність інструментів рефакторингу) угорська нотація дала вам це

Вартість в наші дні жахливих імен, які вона виробляє, занадто висока, але це порівняно недавня річ. Існує ще багато коду, який передував описаним мною розробкам IDE.


1
Якщо я не помиляюся, це ще одна відповідь, яка стосується іншого типу угорської нотації, ніж ту, про яку просить ОП.
MatrixFrog

2
Ця відповідь описує те, що називалося "Система Угорська", де префікс позначає "тип" на рівні мови. Питання задається про "Угорські програми", де слово "тип" не було зрозуміло неправильно і означає семантичний тип. Системи Угорська майже загалом засуджені в наші дні (і це справедливо; це збіднення справжньої мети угорського notaion). Угорські програми, однак, можуть бути хорошою справою.
cHao

Редактори, здатні шукати sCustomer, не підбираючи sCustomerName (vi та emacs - це 2 приклади) існували з 70-х.
Ларрі Коулман

@Larry, можливо, але ви не змогли змусити їх працювати в системах, які я програмував у 80-х
11:12

@cHAo, Ні, ні. Моя думка намагалася пояснити, чому люди вводять додаткову інформацію взагалі в імена змінних. Я старанно уникав згадувати будь-яку версію угорської нотації. Можливо, приклад, який я наводив у розділі "чому пошук і заміна не працює на вихідний код", виглядає як "Система Угорська", але це не було призначено. Я видалив провідні "s", щоб уникнути плутанини.
mcottle

0

Правильно!

Поза цілком нетипізованими мовами, такими як Assembler, угорська нотація є зайвою і дратівливою. Удвічі, коли ви вважаєте, що більшість IDE перевіряють безпеку типу, як ви, er, type.

Додаткові "i", "d" і "?" префікси просто роблять код менш читабельним і можуть бути справді оманливими - як коли "корова-оркер" змінює тип iaSumsItems з Integer на Long, але не турбує рефакторинг назви поля.


9
Ваша відповідь говорить про те, що ви не розумієте різниці між оригінальною, розумною угорською програмою «Програми» та німою бастардізацією під назвою «Системи» угорською. Читати joelonsoftware.com/articles/Wrong.html
Райан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.