Оберон-технология: особенности и перспективы |
Тематика обсуждения: Оберон-технология. Особенности, перспективы, практическое применение.
Всего в теме 6256 сообщений
Добавить свое сообщение
Отслеживать это обсуждение Обсуждение из раздела Школа ОБЕРОНА
№ 5106 27-08-2007 00:25 | |
Ответ на »сообщение 5103« (Руслан Богатырев)
___________________________
Благодарю.
№ 5105 27-08-2007 00:22 | |
Ответ на »сообщение 5101« (Руслан Богатырев)
___________________________
Заранее благодарен.
№ 5104 26-08-2007 22:58 | |
Ответ на »сообщение 5097« (Илья Ермаков)
О чём речь? "Ошибки нижележащих подсистем" - это что?
Обычные такие ошибки - кончилось место на диске, оборвалась связь и т.п. Давай для определенности называть их "физическими". "Программные" ошибки можно пока исключить из рассмотрения.
Пусть есть некоторый сервис (запись DVD) и низкоуровневый интерфейс к нему I0.
Нет. Пример был обратный. Компонента записи DVD использует высокоуровневый интерфейс для получения данных для записи. Если я правильно понял твою мысль, то ты предлагаешь начиная с какого-то уровня превращать физические ошибки в программные (нарушения постусловия). Для компоненты записи DVD это означает невозможность нормально обработать какую-нибудь ошибку сети или ошибку чтения файла (в случае программной ошибки ты предлагаешь перезапускать всю систему).
Очевидно, что разность между силой постусловий требуется где-то между слоями компенсировать...
Одно из решений - что I1.RecordDVD внутри себя умеет решать проблемные ситуации, о которых информирует I0, и доводить выполнение работы до конца.
Вот уж чего компонента записи DVD точно не хочет, так это обрабатывать конкретные ошибки сети или т.п. Она хочет залогать такую ошибку и корректно завершить сессию.
ВТорой подход получил название "обработки исключений", которая бывает самая разная. Но в массовых языках получила распространение конкретная схема с try-catch в той или иной форме (т.е. с прерыванием выполнения).
В "Дизайне и эволюции C++" описывается почему именно для исключений в C++ комитетом была выбрана семантика завершения (то, что ты называешь try/catch), а не семантика восстановления (то, что предлагаешь ты). Вот цитата:
Последний довод был подкреплен еще и теоретическим рассуждением Флавия Кристиана (Flaviu Cristian), который доказал, что при наличии завершениия семантика возобновления не нужна [Cristian, 1998].
Потратив два года на споры, я вынес впечатление, что можно привести убедительные логические доводы в пользу любой точки зрения. Они имелись даже в специальной работе [Goodenough, 1975] по обработке исключений. Мы оказались в положении все тех же античных философов, которые так яростно и умно спорили о природе Вселенной, что как-то забыли о ее изучении. Поэтому я просил любого, кто имел реальный опыт работы с большими системами, представить конкретные факты.
Свое утверждение Митчелл подкрепил рассказом о работе над несколькими операционными системами. Самым главным был пример системы Cedar/Mesa, которую написали программисты, любившие и умевшие пользоваться семантикой возобновления. Однако через десять лет в системе из полумиллиона строк остался лишь один случай использования возобновления — в запросе контекста. Поскольку и в данной ситуации оно фактически было не нужно, механизм возобновления исключили полностью, после чего скорость работы этой части системы значительно возросла. Во всех тех случаях, когда применялась операция возобновления (а это более десяти лет эксплуатации), появлялись определенные проблемы и приходилось искать более подходящий механизм. По сути дела, все применения возобновления были связаны с неумением отделить друг от друга различные уровни абстракции.
№ 5103 26-08-2007 16:47 | |
Ответ на »сообщение 5098« (Дядя .СЭМ)
___________________________
Руслан в »сообщение 4323« вы писали о Л. В. Канторовиче и в частности упоминали:
>Он ввел в рассмотрение составные данные как объект программы и определил понятие дескриптора ("маркер", определяющий способ доступа к компонентам динамического объекта). Предложил "геометрические операции" — правила композиции составных объектов из простых.
Не могли бы вы дать ссылки на работы где он об этом писал. Было бы интересно ознакомиться.
Вот источник информации: А.П.Ершов, М.Р.Шура-Бура "Становление программирования в СССР (начальное развитие)", 1976
См. с.30, также c.23.
Упомянутая работа есть на EuroProg: http://www.europrog.ru/book/prae1976r.pdf
Размер PDF -- 4,87 Мбайт.
О крупноблочном программировании Канторовича и системе "Прораб" см. на замечательном сайте "Леонид Канторович: путь в науке" http://www.kantorovich.icape.ru/big_prog.html
Рекомендую внимательно изучить две работы Л.В.Канторовича:
1. "Об одной математической символике, удобной при проведении вычислений на машинах" (Доклады Академии наук СССР, 1957) -- http://www.kantorovich.icape.ru/biblio/097.pdf
2. "О проведении численных и аналитических вычислений на машинах с программным управлением" (Академия наук Армянской ССР, 1957).
http://www.kantorovich.icape.ru/biblio/098.pdf
О синтаксических деревьях (деревьях Канторовича) см., например, фундаментальный труд проф. Ф.Бауэра -- "Информатика. Вводный курс (в двух частях)", 1990.
В PDF: http://www.europrog.ru/book/infb1990r.pdf (29 Мбайт)
В DjVu: http://www.europrog.ru/book/infb1990r.djvu (6,96 Мбайт)
См. главу 8 "Определение синтаксиса и семантики алгоритмических языков".
№ 5102 26-08-2007 15:31 | |
Ответ на »сообщение 5096« (Сергей Перовский)
___________________________
Поехали по двадцать пятому разу...
Расширение типа и ООП семантически эквивалентны.
(Это generic bus - то, не ООП?)
Сергей, простой пример.
TYPE T0 = RECORD END;
TYPE T1 = RECORD (T0) i: INTEGER END;
Это и есть пример расширения типа (type extension) в классическом Обероне. Какое это имеет непосредственное отношение к ООП? Можно говорить о типе и подтипе. О возможности полиморфной работы с такими родственными типами. Но и все.
№ 5101 26-08-2007 15:27 | |
Ответ на »сообщение 5098« (Дядя .СЭМ)
___________________________
Не могли бы вы дать ссылки на работы где он об этом писал. Было бы интересно ознакомиться.
Конечно. По Канторовичу я уточню работу и постараюсь дать ссылки.
№ 5100 26-08-2007 14:42 | |
Ответ на »сообщение 5096« (Сергей Перовский)
___________________________
Ответ на »сообщение 5092« (Руслан Богатырев)
___________________________
Поехали по двадцать пятому разу...
Расширение типа и ООП семантически эквивалентны.
Расширение типа в классическом Обероне - более технический, низкоуровневый в некотором смысле механизм. В рамках которого может быть реализовано традиционное ООП. С ручной виртуализацией через процедурные поля. С большей гибкостью, но меньшей прямотой для прикладных задач. И опять же, разделение типа данных и процедур, которые независимы и соединяются исключительно на этапе выполнения. Отсюда расширение типа никак не ведёт к наследованию реализации (его опять же можно реализовать через логику инсталляции процедурных полей в конкретной фабрики).
Для системных задач имеем большое пространство для манёвра. Для прикладников часто - только лишнюю мороку...
№ 5099 26-08-2007 14:33 | |
Ответ на »сообщение 5083« (Стэн)
___________________________
Ответ на »сообщение 5082« (Geniepro)
___________________________
Совсем недавно мы с Ильей здесь обсуждали, что компонентность плохо дружит и с IoC, и с мониторами, и с Активными Объектами...
Да, но это проблема "младенческого состояния" многих технологий параллельного программирования, а отнюдь не компонентности...
Та же модель Вашей библиотеки акётров с компонентностью должна дружить, более того, многие опорные требования Вы формулировали именно из предположения, сходного с компонентностью ("актёры ничего не знают друг про друга").
№ 5098 26-08-2007 14:31 | |
Руслан в »сообщение 4323« вы писали о Л. В. Канторовиче и в частности упоминали:
Он ввел в рассмотрение составные данные как объект программы и определил понятие дескриптора ("маркер", определяющий способ доступа к компонентам динамического объекта). Предложил "геометрические операции" — правила композиции составных объектов из простых.
Не могли бы вы дать ссылки на работы где он об этом писал. Было бы интересно ознакомиться.
№ 5097 26-08-2007 14:28 | |
Ответ на »сообщение 5074« (pepper)
___________________________
Ответ на »сообщение 5072« (Илья Ермаков)
___________________________
и позволяет модулям верхнего уровня и конкретного приложения инсталлировать в нужную точку свой обработчик исключения.
Вот есть подсистема записи DVD. Откуда приходят данные на запись ей все равно (из сети или с перфоленты). Какой обработчик, куда его инсталлировать, и чего в нем делать, чтобы корректно обработать ощибки нижележащих подсистем и не запороть болванку?
При обнаружении проблемы модуль низшего уровня может запросить обработку проблемы у инсталлированного обработчика и только если обработчик не иснталлирован, или восстановление невозможно - тогда модуль обязан сгенерировать треп нарушения инварианта.
Ты мешаешь в кучу ошибки внешнего мира (вполне запланированные) и программные ошибки (незапланированные нарушения инварианта). Все таже проблема отсутствия субтипизации...
Ответ на »сообщение 5074« (pepper)
___________________________
Ответ на »сообщение 5072« (Илья Ермаков)
___________________________
и позволяет модулям верхнего уровня и конкретного приложения инсталлировать в нужную точку свой обработчик исключения.
Вот есть подсистема записи DVD. Откуда приходят данные на запись ей все равно (из сети или с перфоленты). Какой обработчик, куда его инсталлировать, и чего в нем делать, чтобы корректно обработать ощибки нижележащих подсистем и не запороть болванку?
О чём речь? "Ошибки нижележащих подсистем" - это что? Если подразумеваются "глюки", то при разработке на нормальных языках об их обработке в конечной версии приложения задумываться как-то не приходится. В случае пользовательских приложений никакой их обработки кроме прекращения работы по нарушению утверждений быть не может (в случае задач пов. надёжности эта проблема решаться, конечно, будет - но отнюдь не языковыми средствами, а на уровне перезапуска с восстановлением целых подсистем, которое осуществляется третьей стороной - диспетчером восстановления...).
Если подразумеваются ошибки "физической реальности" (болванки/привода и т.п.), то об этом я и вёл речь ранее.
Пусть есть некоторый сервис (запись DVD) и низкоуровневый интерфейс к нему I0. Мы строим слой более высокого уровня I1, скрывающий детали работы низкого уровня. Логично также убрать с верхнего уровня работу с ошибками, т.е. "усилить постусловия" инерфейса.
Если I0 имеет вид что-то типа RecordDVD(IN p1,..,pn; OUT error) и гарантирует постусловия ("данные успещно записаны") OR (error IN {"мн-во возможных ошибок"}), то в I1 мы хотим видеть нечто вроде RecordDVD(IN p1,..pk), где кол-во параметров k стало меньше n, и гарантируется постусловие ("данные успешно записаны").
Очевидно, что разность между силой постусловий требуется где-то между слоями компенсировать...
Одно из решений - что I1.RecordDVD внутри себя умеет решать проблемные ситуации, о которых информирует I0, и доводить выполнение работы до конца.
Однако на практике I1 может просто не иметь возможности разрешить эти ситуации (его "сектор ответственности" слишком мал для принятия решения, требуемое поведение зависит от потребностей клиентского кода и т.п.).
Отсюда два выхода - либо вернуться к явному вовзрату кодов ошибок (сквозному через все уровни), либо делегировать решение проблемы "наверх" через какие-то дополнительные "каналы связи". Первый подход сильно портит картину с "выскоуровневостью" - клиенты всюду должны обрабатывать все коды ошибок и знать, как решать проблемы...
ВТорой подход получил название "обработки исключений", которая бывает самая разная. Но в массовых языках получила распространение конкретная схема с try-catch в той или иной форме (т.е. с прерыванием выполнения). Начнём с того, что эта схема вообще не решает проблему, т.к. не даёт сужения постусловия (для I1 мы снова имеем ("данные успешно записаны") OR (сгенерировано исключение..)). Единственный плюс перед явными кодами ошибок - клиентский код становится чище, освобождаясь от повсеместных проверок. Исключение всплывёт до некоторого уровня, где его ожидает обработчик. Т.е. предполагается, что где-то выше по стеку активаций есть процедура-"супервизор", которая в состоянии разрешить проблему и провести восстановление. Увы, это предположение терпит полный крах в параллельных и тем более в компонентных системах. Там "выше по стеку" часто никак не связано с "выше по уровню в системе". Часть системы, способная принимать решения по восстановлению, иожет выполняться совершенно другой активностью, либо быть отделённой косвенностью ОО-паттернов и т.п.
Вот отсюда и получаем, что механизм try-catch совершенно не решает ту проблему, для которой он как бы был предназначен... Более того, он вообще не решает никакой проблемы. Кроме проблемы "обёртывания глюков", которой при нормальном программировании просто не должно возникать.
Отсюда и возникает идея использовать паттерн Inversion of Control, с помощью инсталлируемых ОО-рахъемов. "Супервизорская" часть системы подключается через такой разъём к I1. I1 чётко определяет набор возможных сообщений "наверх" и набор обратных сообщений, которые позволят ему "закрыть разницу постусловий". В случае ошибки на уровне I0 I1 может попробовать решить проблему своими силами, а если не получится - обратиться через имеющийся у него разъём выше - к супервизорской части системы, получить данные для восстановления - и таки выполнить операцию, соблюдя предусловия. Либо, если восстановление невозможно, то супервизорская часть может принять решение о каких-то других действиях, уже без завершения обработки запроса..
В общих чертах так.
Добавить свое сообщение
Отслеживать это обсуждение
Дополнительная навигация: |
|