Оберон-технология: особенности и перспективы |
Тематика обсуждения: Оберон-технология. Особенности, перспективы, практическое применение.
Всего в теме 6256 сообщений
Добавить свое сообщение
Отслеживать это обсуждение Обсуждение из раздела Школа ОБЕРОНА
№ 3466 24-03-2007 18:12 | |
Ответ на »сообщение 3463« (Geniepro)
___________________________
Ответ на »сообщение 3459« (AVC)
___________________________
В каком смысле "мусором"?
В Обероне используются раздельная компиляция и межмодульный контроль типов.
Просто "мусор" (в отличие от Си) туда не запишешь.
Типобезопасность - это, конечно, хорошо, но не достаточно. Может ли модуль А проверить, выполняет ли реально модуль AImpl (или B, а затем C) некие контракты, которые заявляет?
Можно соблюсти все типы, но при этом реализовать бессмысленные или просто опасные алгоритмы. Как это будет определено/перехвачено/запрещено? О какой надёжности тут может идти речь, если любой, какой попало модуль, может перезаписать какие-то базовые функции, только потому, что автор базовых модулей надеется на добропорядочность других программистов?
Перезапись производится не присваиванием, а вызовом Set-процедур модуля. Set-процедура в Обероне может элементарно проверить, какой модуль ее вызвал, и в случае нарушения привилегий послать "недобропорядочный перезаписыватель" куда подальше...
Что именно имеется в виду?
В идеале - модуль А должен предоставлять некоторый сервис, причём не позволять кому попало его переопределять.
А если сервис не так прост, чтобы A мог его самостоятельно предоставить?
Например, если реализация сервиса платформенно-зависима, а у вас стоит задача кроссплатформенной реализации? В "разъемной" парадигме архитектура строится элементарно - выделяются модули для использования конечными разработчиками, которые предоставляют интерфейсы к некоторым сервисам, но содержат в себе только платформенно-независимую часть. Платформенно-зависимые модули не импортируются никем. Они загружаются конфигурационным модулем и региструют свои разъемы в платформенно-независимых модулях.
Таким образом, вся платформенно-независимая часть не требует ни переписывания, ни перекомпиляции (если аппаратная база та же).
Например, все модули BlackBox Framework - а значит и пользовательские модули - не потребуют перекомпиляции под Линукс, потому что в них нет ни платформенно-зависимого кода, ни импорта платформенно-зависимых модулей. Вся "платформа" - в лежащей сбоку и никем не импортируемой подсистеме Host.
В идеале - модуль А должен предоставлять некоторый сервис, причём не позволять кому попало его переопределять.
"В идеале электрическая розетка должна предоставлять электрический ток сама, причем не позволять кому-то со стороны его передавать - а вдруг на электростанции напряжение подскочит?"
Представьте себе, что пресловутый модуль A с точкой доступа к некоторому сервису - это монтажная плата с разъемами и "обвязкой", к которой вы подключаетесь. А конкретная реализация подключается через другие, отдельные разъемы, отдельными заменяемыми модулями - и вам абсолютно все равно, какая реализация сейчас стоит... Например, доступ к HDD производится чипсетом материнской платы через фиксированный интерфейс с контроллером HDD. Но это же не значит, что контроллер HDD сам реализует нужный сервис! Нет. Он предоставляет разъемы, в которые "втыкается" конкретная реализация накопителей, и чипсету с процессором глубоко плевать, какая... При этом при мощной "обвязке" типа SCSI или SATA можем менять реализацию "на горячую"...
№ 3465 24-03-2007 18:02 | |
Ответ на »сообщение 3463« (Geniepro)
___________________________
Типобезопасность - это, конечно, хорошо, но не достаточно. Может ли модуль А проверить, выполняет ли реально модуль AImpl (или B, а затем C) некие контракты, которые заявляет?
Можно соблюсти все типы, но при этом реализовать бессмысленные или просто опасные алгоритмы. Как это будет определено/перехвачено/запрещено? О какой надёжности тут может идти речь, если любой, какой попало модуль, может перезаписать какие-то базовые функции, только потому, что автор базовых модулей надеется на добропорядочность других программистов?
Вопрос очень хороший.
Но, по сути, он не настолько уж связан (или все-таки связан?) с "инверсией импорта", о которой говорит Илья Ермаков.
Как, например, гарантировать, что импортируемая функция sin не возвращает значение другой функции, скажем cos? Ведь формально этому ничего не мешает.
№ 3464 24-03-2007 17:56 | |
Ответ на »сообщение 3461« (AVC)
___________________________
У меня складывается впечатление, что применимость ФП ограничена "программированием в малом" (где оно весьма перспективно).
Думаю, наиболее комфортно ФП себя чувствует в малом программировании (алгоритмы, допускающие композицию функций), а также в сверхбольшом программировании -- композиция модулей на кластерно-компонентном уровне.
Как отмечал Вирт еще в середине 1960-х годов, когда особенно плотно занимался лямбда-исчислением и применимостью ФП для задач обобщения императивных конструкций, для ФП чужеродны две ключевых вещи императивного программирования: присваивание и переход.
Вообще-то я очень рекомендую обеим сторонам на время заключить "водяное перемирие" и очень внимательно разобрать работы 1963-1966 гг. по первому виртовскому языку Euler:
1. A Generalization of ALGOL
http://www.europrog.ru/paper/nw1963-01e.pdf
2. Euler: A Generalization of Algol, and its Formal Definition
http://www.europrog.ru/book/eunw1965e.pdf
3. EULER: A Generalization of ALGOL, and Its Formal Definition. Part 1
http://www.europrog.ru/paper/nw1966-01e.pdf
4. EULER: A Generalization of ALGOL, and Its Formal Definition. Part 2
http://www.europrog.ru/paper/nw1966-02e.pdf
Найдете массу интересного, заслуживающего всестороннего обсуждения в свете баталий по Оберону-Хаскелю, а также МП-ФП-ООП. Поймете, откуда пошла пресловутая коммутация и type test, что перепробовал Вирт, прежде чем пришел к своему Оберону.
№ 3463 24-03-2007 17:52 | |
Ответ на »сообщение 3459« (AVC)
___________________________
В каком смысле "мусором"?
В Обероне используются раздельная компиляция и межмодульный контроль типов.
Просто "мусор" (в отличие от Си) туда не запишешь.
Типобезопасность - это, конечно, хорошо, но не достаточно. Может ли модуль А проверить, выполняет ли реально модуль AImpl (или B, а затем C) некие контракты, которые заявляет?
Можно соблюсти все типы, но при этом реализовать бессмысленные или просто опасные алгоритмы. Как это будет определено/перехвачено/запрещено? О какой надёжности тут может идти речь, если любой, какой попало модуль, может перезаписать какие-то базовые функции, только потому, что автор базовых модулей надеется на добропорядочность других программистов?
Что именно имеется в виду?
В идеале - модуль А должен предоставлять некоторый сервис, причём не позволять кому попало его переопределять.
№ 3462 24-03-2007 17:37 | |
Ответ на »сообщение 3458« (Geniepro)
___________________________
Ответ на »сообщение 3456« (Илья Ермаков)
___________________________
Это потенциально очень опасно. Кто запретит какому-то левому модулю перезаписать эти "разъёмы" всяким мусором?
Другое дело, если бы в Оберонах была возможность частичного экспорта "только для избранных", но в этом случае ваш трюк уже будет иметь некоторые ограничения.
Это не опасно в рамках обычного ПО. Более того, другого способа построения компонентной архитектуры "науке неизвестно". Другой вопрос, когда мы переходим к работе с модулями из произвольных (потенциально опасных) источников, т.е. от простых компонентных систем, когда компоненты имеют одинаковый уровень доверенности, к системам с разными уровнями доверия. Например, апплеты из Интернета - как запретить им нарушать целостность систем?
Это требует отдельного уровня безопасности, но также не является проблемой.
В частности, в Обероне, используя метамеханизмы, любая процедура модуля A может выяснить, какой модуль ее вызвал, проверить его права на выполнение тех или иных действий...
Процедуры переустановки разъемов могут иметь высший уровень защиты и работать только с доверенными модулями. Можно реализовать любую политику...
Однако инверсия импорта и дианмические разъемы - это аксиома компонентности, и без этого никуда...
№ 3461 24-03-2007 17:36 | |
У меня складывается впечатление, что применимость ФП ограничена "программированием в малом" (где оно весьма перспективно).
Имеется в виду: выполнить ту или иную функцию между точками изменения и расширения программной системы.
№ 3460 24-03-2007 17:33 | |
Ответ на »сообщение 3457« (Руслан Богатырев)
___________________________
А Си господствовал сначала в классе микрокомпьютеров (епархии DEC), где и появился на свет.
Разумеется, не микро-компьютеров, а мини-компьютеров.
№ 3459 24-03-2007 17:20 | |
Ответ на »сообщение 3458« (Geniepro)
___________________________
>>>Это потенциально очень опасно. Кто запретит какому-то левому модулю перезаписать эти "разъёмы" всяким мусором?
В каком смысле "мусором"?
В Обероне используются раздельная компиляция и межмодульный контроль типов.
Просто "мусор" (в отличие от Си) туда не запишешь.
>>>К тому же тут нарушается один из основных принципов модульности - information hiding, ведь модуль А вынужден экспортировать кучу ненужных для его "законных" клиентов вещей, вместо того, что бы спрятать их в себе...
Что именно имеется в виду?
Допустим (для простоты), экспортируется процедурная переменная.
А что еще?
В принципе, можно было бы экспортировать процедурную переменную только "для чтения" (а то и вовсе не экспортировать ее, а вызывать косвенно) и переустанавливать ее с помощью специальной процедуры (что-то вроде SetHook* ), проверяющей для надежности какую-нибудь цифровую подпись (например, "драйвер от дяди Васи" :) ).
Но это вариации и детали, не влияющие на сам принцип.
№ 3458 24-03-2007 17:07 | |
Ответ на »сообщение 3456« (Илья Ермаков)
___________________________
Пусть у нас есть модуль A, предоставляющий какой-то сервис и высокоуровневые интерфейсы к нему, и модуль AImpl - с низкоуровневой платформенно-зависимой реализацией сервисов A.
Естественный и первый позыв - импортировать из A AImpl. Однако в компонентной архитектуре все наоброт - A вообще ничего не знает про AImpl, он только предоставляет разъемы для его подключения. Импорт реверсирован - AImpl импортирует A и подключается к нему по разъемам.
AImpl никем более не импортируется. В нужный момент мы можем его выгрузить, загрузить другую реализацию, которую закоммутировать к A. При этом ни один из клиентов A не заметит подмены.
Это потенциально очень опасно. Кто запретит какому-то левому модулю перезаписать эти "разъёмы" всяким мусором?
К тому же тут нарушается один из основных принципов модульности - information hiding, ведь модуль А вынужден экспортировать кучу ненужных для его "законных" клиентов вещей, вместо того, что бы спрятать их в себе...
Другое дело, если бы в Оберонах была возможность частичного экспорта "только для избранных", но в этом случае ваш трюк уже будет иметь некоторые ограничения.
А когда в ОС вы устанавливаете драйвер, к примеру, монитора, то он - о ужас!! - внедряет "свои сущности" в область ядра операционной системы - а авторы операционной системы даже не подозревали о наличии вашего драйвера для экзотической видеокарты из провинции Шунь-Янь КНР!
Драйвера должны соответствовать некоторым стандартным API.
Т.е. по сути драйвер - объект жёстко описанного типа, предоставляющий какие-то стандартные методы, при этом ему вовсе не обязательно работать по Вашему способу.
№ 3457 24-03-2007 17:02 | |
Ответ на »сообщение 3442« (Булат Зиганшин)
___________________________
кстати, вам возможно будет интересно http://rsdn.ru/Forum/Message.aspx?mid=2339757&only=1 где я анализирую причину победы в 80-х годах C/C++ как наиболее популярного языка прграммирования
в 80-х было три конкурирующих языка процедурного программирования — С, паскаль, модула-2. для прикладного программирования наилучшим, имхо, была модула.
Приятно слышать такую позитивную оценку языка, но техническое совершенство и популярность -- две вещи несовместные. В 1980-х годах (ближе к концу) сфера системного программирования уже была почти полностью оккупирована Си. Паскаль успешно конкурировал с ним по популярности, но сфера их пересечения была только в образовании, где Си проигрывал Паскалю.
На самом деле Паскаль Виртом создавался с прицелом совсем не на образование (это приятное следствие), а на другую область, где он долгое время был вне конкуренции -- на разработку трансляторов (как компиляторов, так и интерпретаторов). При этом Паскаль опережал Си в классе мэйнфреймов и на микропроцессорах, взлетев на волне ПК-революции на крыльях сначала UCSD Pascal, а затем и передранного с него Turbo Pascal. Взлетел не столько благодаря своему технологическому совершенству (по меркам того времени), сколько из-за неуемной энергии многих расторопных американцев сделать на нем деньги (что и было сделано). А Си господствовал сначала в классе микрокомпьютеров (епархии DEC), где и появился на свет. Лишь потом он распространил свое влияние (во многом через интерес к UNIX) на уйму платформ, а вслед за этим и в сферу прикладного программирования и образования.
Что касается Модулы-2, то у нее был более популярный и могущественный конкурент в лице Ады. Модула-2 успела рвануть в сфере телекоммуникаций (на какой-то момент став там стандартом де-факто) и в области разработки встроенных систем (то, что оставалось от всепожирающей Ады). Для Ады долго было проблемой попасть на ПК, но когда проблема разрешилась, на фоне ISO-стандартизации Модулы-2 в период покорения "Нового Света" в лице ООП виртовская Модула-2 была по сути похоронена.
в области ООП были представлены Эйфель, С++ и Objective C.
Эйфель (1986) тогда знал сам автор и пара его коллег. ООП в научном мире был известен по Симуле-67. А в мире разработчиков ООП известно по раскрутке Smalltalk (1972-1980), на которую решились выходцы из Xerox PARC, глядя на наплевательское отношение компании Xerox и на миграцию ценнейших кадров в Microsoft, Apple, а затем в NeXT. Система Smalltalk-72 претерпела несколько эволюций вплоть до самой известной — Smalltalk-80 и после ряда публикаций (прежде всего, в BYTE) стала восприниматься не просто как игрушка с пользовательским интерфейсом, а как самостоятельное направление в конструировании программ разного уровня сложности. Реальный старт ООП в массовом сознании состоялся с выходом C++ (1983; C with Classes -- 1980), Objective C (1984) и Object Pascal (1985, версии Apple, а не Borland с тем же названием годы спустя!). Про историю C++ можно посмотреть, например, в одной из моих статей: http://www.osp.ru/pcworld/2003/01/164806/
Но с момента ее написания и публикации много воды утекло и для меня много новой информации появилось. Если вкратце: язык C++ было выгодно раскручивать на волне новой панацеи -- ООП. Главным мотором, вовремя подгоношившимся и сумевшим быстро сократить здесь отставание от других и возглавить "пелетон", был Microsoft. Без этого C++ не был бы на той вершине, на которую его вознесли сильные мира сего. Это важно понимать.
Добавить свое сообщение
Отслеживать это обсуждение
Дополнительная навигация: |
|