Чи існує теорія ієрархій винятків?


18

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

  1. Здається, немає загальної моделі чи ієрархії винятків. Кожна мова в основному згортає свою власну версію, і якщо винятки перетворюють її на стандарт, то види винятків, які можна знайти в стандарті, були б досить довільними (в основному ті, які були реалізовані під час створення мовних інструментів, таких як читання вихідного коду з рядок або виняток, щоб викликати налагоджувач, або той, який відбувається, коли файл неможливо знайти тощо)

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

Це виглядає для мене жахливим упущенням. Чому ніхто не знає, які помилки знадобляться в програмах користувача? Я сподівався, що існує якась приємна ієрархія, подібна до числових типів, колекцій, об'єктної системи тощо.

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

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

(Функціональна теорія винятків, Майк Співі, 1988)

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

Питання:

Чи існує теорія винятків? Якщо так, як це називається? Назвіть основи цього, якщо такі є наріжним каменем?


винятки - це досить новий винахід, можливо, менше ~ 20 років, який виникає дещо із "longjmp" на C. вони здебільшого підключені до ООП. здається, ідеальне використання / теорія / найкращі практики все ще перебувають у розвитку. java має одну з більш досконалих моделей. Як ви зазначаєте, існує багато "антимакетів", що стосуються винятків. дещо з цього пов'язане з теорією "відмовостійких обчислень", яка також здається дещо зародженою загалом.
vzn

Ви можете виключити винятки як підмножину теорії продовження. Дивіться en.wikipedia.org/wiki/Continuation
jmite

@jmite Виключення та продовження дуже різні. Винятки динамічно пов'язуються зі своїми обробниками, тоді як продовження - це статично. Взагалі, продовження самостійно не можна використовувати для впровадження винятків, принаймні, за наявності типів, див., Наприклад, Набрані винятки та продовження не можуть макро-виразити один одного .
Мартін Бергер

"Винятки, визначені мовою, дуже рідко використовуються програмами користувача." Це так правда! Визначення спеціальних винятків дуже рідко потрібно. Наприклад, python та його stdlib визначають щось на зразок 160 винятків. Шанси, що виняток, про який ви думаєте, не було визначено, дуже малі. Про деякі (більшість?) Цих винятків широко не відомо. Наприклад, це LookupErrorбуло б чудово добре для кожного спеціального контейнера, але я багато людей навіть не знаю, що він існує.
Бакуріу

1
@jmite Ще одна зустріч у мене була з винятками, перш ніж ця тема була з книги Бенджаміна К. Пірса, типи та мови програмування. Де він згадує про помилки в контексті визначення типу функції. Тобто, з його точки зору, помилки - це лише ще одне значення, повернене з функцій (і разом з іншим аргументом вони утворюють цілий тип, якщо мені це дозволяють сказати).
wvxvw

Відповіді:


8

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

  • Б. Ренделл, Структура системи для відмов програмного забезпечення.
  • JB Goodenough. Обробка винятків: питання та запропонована нотація.
  • JB Goodenough. Структурована обробка виключень.
  • BG Ryder, ML Soffa, Вплив на дизайн поводження з винятками.
  • D. Teller, A. Spiwack, T. Varoquaux, Спіймай мене, якщо зможеш: Назустріч безпечному типу, ієрархічному, легкому, поліморфному та ефективному керуванню помилками в OCaml.
  • X. Leroy, F. Pessoux, Типовий аналіз невловимих винятків.
  • R. Miller, A. Tripathi, Проблеми з обробкою винятків в об'єктно-орієнтованих системах.
  • S. Drew, KJ Gough, J. Ledermann, Реалізація обробки нульових накладних винятків.
  • B. Структура, безпека винятку: поняття та методи.
  • Д. Малаєрі, Дж. Олдріх, Технічні характеристики винятку.
  • Х. Накано, Конструктивна формація механізму лову та кидання.
  • А. Наневський, Модальне обчислення для обробки винятків.
  • П. де Гроот, Просте обчислення винятків.
  • Х. Тілеке, Про винятки та продовження в присутності держави.
  • JG Riecke, H. Thielecke, набрані винятки та продовження не можуть макро-виразити один одного.
  • M. van Dooren, E. Steegmans, Поєднуючи надійність перевірених винятків із гнучкістю неперевірених винятків, використовуючи прив’язані декларації про виключення.
  • JA Vaughan, Логічне тлумачення винятків у стилі Java.
  • С. Марлоу, С. Пейтон Джонс, А. Моран, Асинхронні винятки в Хаскеллі.
  • B. Jacobs, F. Piessens, Failboxes: Напевно безпечне поводження з винятками.

Ого, спасибі велике! Мені знадобиться кілька місяців (якщо не більше), щоб повернутися з позитивною відповіддю :) Зараз я розірвався між кількома книгами, не знаючи, з чого почати!
wvxvw

2
Багато цих робіт стосуються впровадження або моделювання винятків у мовах програмування, а не про те, як створити ієрархії винятків. Не могли б ви поповнити список відповідними документами?
Жил "ТАК - перестань бути злим"

@Gilles Початкове запитання було трохи незрозумілим. Я вважаю, що те, що вважається відповідним винятком, залежить, головним чином, від програми. Єдиною реальною теоретичною проблемою з винятками є компроміс між (1) з'єднанням незв'язаних модулів через винятки (саме тому жодна мова після Java не має обов'язкових специфікацій винятків) (2), що дає користувачеві модуля деяку вказівку, на які види помилок очікувати , та (3) компілятор довідки щодо обробки помилок. Наскільки я бачу, досі не знайдено переконливого рішення цієї головоломки.
Мартін Бергер

6

Я не знаю, існує чи немає теорії, але може виникнути нова прагматична експериментальна наука.

Найкращим джерелом, про який я можу придумати, є Bjarne Stroustrup, The Design and Evolution of C ++, Addison-Wesley, 1994 . Якщо я правильно пам’ятаю (це дуже хороша книга, і люди продовжують позичати її у мене, а не повертати її, тому в даний момент у мене немає копії) є розділ про винятки. Комітет C ++ в рамках Stroustrup вимагав багато емпіричних доказів того, що запропонована функція необхідна, перш ніж вони будуть готові додати її до мовного визначення. Сторінка Вікіпедії про винятки містить таку цитату з цієї книги:

На зустрічі Пало Альто [стандартизація C ++] у листопаді 1991 року ми почули блискучий підсумок аргументів щодо семантики припинення, підкріплених як особистим досвідом, так і даними Джима Мітчелла (від Sun, раніше від Xerox PARC). Джим використовував обробку винятків на півтисячі мов протягом 20 років і був раннім прихильником відновлення семантики відновлення як один з головних розробників та впроваджувачів системи кедрів / меси Xerox. Його повідомлення було припинення переваги над відновленням; це не питання думки, а питання багаторічного досвіду. Відновлення спокусливе, але недійсне. Він підкріпив це твердження досвідом декількох операційних систем. Ключовим прикладом був Кедр / Меса: його написали люди, яким сподобалось та використали відновлення, але після десяти років використання, у системі півмільйона ліній залишилось лише одне використання відновлення - і це було розслідуванням контексту. Оскільки відновлення насправді не було необхідним для такого розслідування контексту, вони усунули його та виявили значне збільшення швидкості в цій частині системи. У кожному випадку, коли було використано відновлення, це протягом десяти років - стало проблемою, і більш підходящий дизайн замінив його. По суті, кожне використання відновлення означало неспроможність утримувати окремі рівні абстракції, що не суперечать. У кожному випадку, коли було використано відновлення, це протягом десяти років - стало проблемою, і більш підходящий дизайн замінив його. По суті, кожне використання відновлення означало неспроможність утримувати окремі рівні абстракції, що не суперечать. У кожному випадку, коли було використано відновлення, це протягом десяти років - стало проблемою, і більш підходящий дизайн замінив його. По суті, кожне використання відновлення означало неспроможність утримувати окремі рівні абстракції, що не суперечать.

У C ++ справжній виграш - RAII , що значно полегшує обробку ресурсів під час помилок. (Це не усуває потреби throwта try- catch, але це означає, що вам це не потрібно finally.)

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

Інша річ, яку люди, здається, навчилися роками, - це те, що специфікації виключень важко правильно викласти мовою. Дивіться, наприклад, це: http://www.gotw.ca/publications/mill22.htm , або це: http://www.gotw.ca/gotw/082.htm . (І це не лише C ++, у програмістів Java також є тривалі аргументи щодо їх досвіду із перевіреними порівняно з неперевіреними винятками .)

Трохи про історію винятків. Класичний документ: John B. Goodenough: "Обробка винятків: питання та запропонована нотація", Commun. ACM 18 (12): 683-696, 1975. Але раніше були відомі винятки. Меса мав їх приблизно в 1974 році, і PL / я, можливо, теж їх мав. Ада мала механізм винятків до 1980 року. Я вважаю, що на винятки C ++ найбільше вплинув досвід роботи з програмою мови програмування Барбари Ліськов приблизно з 1976 року. Барбара Лісков: "Історія CLU" в історії мов програмування --- II , Томас Дж. Бергін-молодший та Річард Г. Гібсон-молодший (ред.). С. 471–510, ACM, 1996 .


Це цікаво, і мені доведеться дослідити більше, щоб відповісти краще. Але, як і раніше: я знаю, що існує дуже сильне заперечення щодо використання винятків у C ++ коли-небудь (можливо, анекдот, але iirc конвенції Google про кодування, які використовуються для заборони використання винятків). Винятки, перевірені Java, безумовно, є унікальним і, таким чином, цікавим експериментом, але ця функція отримала стільки поганих кредитів протягом своєї історії ... більшість людей просто перезавантажують їх під час виконання (хоча це може бути пов'язано лише з синтаксисом).
wvxvw

Мені більше відома класифікація винятків Common Lisp, де вони намагалися (хоча і з невеликим успіхом) розділити їх відповідно до рівня загрози, яку вони становлять для програми. наприклад , serious-conditionпроти simple-condition. Зараз я також читаю Дж. Л. Остінга, де він класифікує помилки (не пов'язані з програмуванням) на групи, грунтуючись на тому, як система не виконала завдання (наприклад, неправильні частини, використані проти нещирих намірів). Що не відразу застосовно до програмування, але може бути після певного вдосконалення.
wvxvw

@Wandering Logic Я upvoded , тому що ви пояснили , чому C ++ excpetios є ками і утворено включення функцій може знищити мову.
Val

@wvxvw very strong objectionПроти винятків у C ++ походить з двох фактів: немає finallyконструкції і ніхто більше не використовує винятки. Перша проблема також посилює другу. Тобто, коли у вас немає finally, ви не можете закрити ресурс, коли відбувається виняток. Оскільки ніхто не використовує винятків, усі функції / API уникають їх, вам потрібно вкласти багато коштів, переробивши всю традиційну інфраструктуру C ++, обернувши всі функції, за винятком, щоб почати отримувати переваги від них у своєму коді. Але нестача finallyробить такий підхід також неможливим.
Вал

@wvxvw: Конвенції Google забороняють викидати винятки через межі модуля (.so). Це пов’язано з тим, що винятки в C ++ використовують інформацію про тип часу виконання (RTTI), і Linux не зробив гарної роботи з впровадженням типізації під час виконання. В Linux ви можете надійно передавати типи часу виконання лише між модулями, якщо ви компілювали модулі з однаковою версією того ж компілятора і пов'язані з ідентичною версією libstdc ++. Дійсно, це взагалі відмова від C ++ спільнотою Linux, а не відмова конкретно винятків.
Мандрівна логіка

3

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


1
Я думаю, що це абсолютно не має значення. Питання полягає не в моделюванні поняття винятків, а в зіставленні його з помилками - я думаю, що правильним способом описати це з точки зору PLT була б теорія ієрархій винятків.
Жил "ТАК - перестань бути злим"

Хм, ти маєш рацію. Я зафіксував відповідь, щоб вказати на це, але думаю, що видаляти її не потрібно. Що ти думаєш?
Андрій Бауер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.