Языки программирования, 16 лекция (от 26 октября)
Материал из eSyr's wiki.
(Содержимое страницы заменено на «== From Ebaums Inc to MurkLoar. == We at EbaumsWorld consider you as disgrace of human race. Your faggotry level exceeded any imaginab...») |
(Отмена правки № 1421 участника 77.132.182.157 (обсуждение)) |
||
Строка 1: | Строка 1: | ||
- | == | + | <P STYLE="margin-bottom: 0cm">Языки программирования 26.10.06</P> |
- | + | <P STYLE="margin-bottom: 0cm"><BR> | |
- | + | </P> | |
- | + | <P STYLE="margin-bottom: 0cm">В прошлый раз мы остановились на | |
+ | межмодульных связях.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Библиотечный модуль Модулы дыва состоит | ||
+ | из двух подмодулей, связанных одним именем.:</P> | ||
+ | <OL> | ||
+ | <LI><P STYLE="margin-bottom: 0cm">Модуль-интерфейс, гнде только | ||
+ | определения</P> | ||
+ | <LI><P STYLE="margin-bottom: 0cm">Модуль-реализация. Реализация и | ||
+ | дополн объявления для неё, а так же инициализирующая часть.</P> | ||
+ | </OL> | ||
+ | <P STYLE="margin-bottom: 0cm">Дельфи:</P> | ||
+ | <P STYLE="margin-bottom: 0cm">физически представляет собой один | ||
+ | модуль, но присутствует понятие ирнтерфейся и реализации, разница | ||
+ | чисто синтаксическая. Есть более тонкие моменты, которые отличают, | ||
+ | они связаны с механизмом межмодульных связей. | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Не разрешаются вложенные моудли.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Возникают два понятия: потенциальная и | ||
+ | непоср видимость.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Непосредственна – конгда имя | ||
+ | можно употреблять без уточнЯюзей информации</P> | ||
+ | <P STYLE="margin-bottom: 0cm">Протенцияалдьная – с уточняющей, | ||
+ | указание имени модуля через точку. Везде через точку, только С++ | ||
+ | выпендрился, там ::</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Непосредственно ыидимыми являются | ||
+ | только имена модулей. Все остальные имена потенциально видимые только | ||
+ | те, что в разделе определений. Имена из модулей-определений видимы | ||
+ | потенциально. Из модуля определений осуществляется экспорт в | ||
+ | глобальное пространство имён.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Все имена равноправны. | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Кроме понятие экспорта, есть понятие | ||
+ | импорта. Импорт может быть как в модуль определений, так и вмоудль | ||
+ | реализации. Таблицпа имён из модуля реализаций – конкатенация | ||
+ | таблицы из модуля поерделений.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Модуль реализации только импортироет, | ||
+ | как из модуля определений (всегда, неявно), так и из других модулей.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Есть две формы импорта:</P> | ||
+ | <P STYLE="margin-bottom: 0cm">IMPORT список модулей.</P> | ||
+ | <P STYLE="margin-bottom: 0cm">Стандартные и пользовательские модули | ||
+ | абсолютно равноправны, при этом реальный ждоступ получаем тогда, | ||
+ | когда делуем предожение IMPORT. Оно должно быьб первым среди всех | ||
+ | объявлений. С точки зрения реализации компилятор должен просмотреть | ||
+ | все папки поиска, и подкачать соотв таблицы имён. При этом соотв | ||
+ | имена в этом модуле, если в нём есть предложение IMPORT, все имена из | ||
+ | него ст ановятся видимы потенциально. Приходиться писать | ||
+ | InOut.WriteLn. Программистов это раздражает, поэтому есть другая | ||
+ | формаи импорта: FROM имя модуля IMPORT список идентификаторов – | ||
+ | и имена становятся видимы непосредственно. Это сделано в дань | ||
+ | программистом, которые ленятся набивать длинные имена. Беда непоср | ||
+ | импорта в конфликте имён. Причём могут конфликтовать как с именами | ||
+ | других модулей, так и с локальными. Локальные имеют больший приоритет | ||
+ | (граждане первого сорта имеют больше прав, относительно иммигрантов). | ||
+ | Это достаточно удобная модель.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Отличия Дельфи:</P> | ||
+ | <P STYLE="margin-bottom: 0cm">Имена из модульной реализации | ||
+ | недоступны никому, но есть едиственная форма предложения импорта: | ||
+ | uses список модулей – импорт непосредственный. Если имена | ||
+ | конфликтуют между собой, то в этом случае непоср видимост снимается. | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">С первой точки зрения этот подход более | ||
+ | улдобен, но когда лектор столкнулся с программированием в Дельфи и | ||
+ | Модуле-2, то на Модуле-2 текст читать приятнее. Ибо когда в uses | ||
+ | полтора десятка модулей, то дрогадаться, из какого модуля | ||
+ | идентификатор, трудно. Поэтому Борланд всегда поставлял ос всеми | ||
+ | своими компиляторами grep. А в Модуле-2 мы обречены на успех при | ||
+ | поиске по файлу.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Порядок загрузки модулей поерделяется | ||
+ | порядком зависимостей. В момент загрузки доступна инициализация – | ||
+ | begin ... end. .</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">В этих языках есть принцип – | ||
+ | РОРИ, Разделение</P> | ||
+ | <OL> | ||
+ | <LI><P STYLE="margin-bottom: 0cm">Определения</P> | ||
+ | <LI><P STYLE="margin-bottom: 0cm">Реализация</P> | ||
+ | <LI><P STYLE="margin-bottom: 0cm">Использования</P> | ||
+ | </OL> | ||
+ | <P STYLE="margin-bottom: 0cm">Главенствовал в ЯП в 70-ч годах, когда | ||
+ | появились ЯП с чёткой модульной структурой.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Есть ли в Си разделение определния и | ||
+ | реализации? Это можно сделать, но ручками. И есть много подводных | ||
+ | камней. Например, каждый хедер начинается с ifndef, дабы избежать | ||
+ | повторного включения модулей. | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">#ifndef SYMBOL</P> | ||
+ | <P STYLE="margin-bottom: 0cm">#define SYMBOL</P> | ||
+ | <P STYLE="margin-bottom: 0cm">...</P> | ||
+ | <P STYLE="margin-bottom: 0cm">#endif</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Интересно с этрой точки зрения | ||
+ | посмотреть на язык Оберон, что же он упростил. История идёт по | ||
+ | спирали, и там от РОРИ с первого взгляда отказалисб.</P> | ||
+ | <P STYLE="margin-bottom: 0cm">В первой версии языка:</P> | ||
+ | <P STYLE="margin-bottom: 0cm">DEFINITION M</P> | ||
+ | <P STYLE="margin-bottom: 0cm">опр-я</P> | ||
+ | <P STYLE="margin-bottom: 0cm">ENDM.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">MODULE M</P> | ||
+ | <P STYLE="margin-bottom: 0cm">ENDM.</P> | ||
+ | <P STYLE="margin-bottom: 0cm">Модно выкинукть понятия модуля | ||
+ | определения как такового. Вместо этого можно просто помечать. То же, | ||
+ | что и в ассемблере.</P> | ||
+ | <P STYLE="margin-bottom: 0cm">MODULE M;</P> | ||
+ | <P STYLE="margin-bottom: 0cm"> TYPE T* - если после имени стоит | ||
+ | звёздочка, то оно экспортируемое</P> | ||
+ | <P STYLE="margin-bottom: 0cm"> REOCRD</P> | ||
+ | <P STYLE="margin-bottom: 0cm"> END;</P> | ||
+ | <P STYLE="margin-bottom: 0cm"> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm"> PROCEDURE P* (X:T);</P> | ||
+ | <P STYLE="margin-bottom: 0cm"> END;</P> | ||
+ | <P STYLE="margin-bottom: 0cm">ENDM.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">На первый взгляд это отступление от | ||
+ | РОРИ. Ибо программисту использующему нужен только интерфейс. На самом | ||
+ | деле, в к концу 80-началу 90х годов получил распространение приём, | ||
+ | что язык пишется как часть системы программирования. | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">//На 3 этаже стояли перфораторы</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Прграммистдимеет делло с программой, | ||
+ | которую просматривает в режиме онлайн.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">С этой точки зрения интересен Eifel, | ||
+ | который генерировал документирующие модули. | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">В современных ЯП (Си шарп, Джава) | ||
+ | интерфейс и реализация не разделяются. На этот шаг пошли потому, что | ||
+ | там есть программы, коотрые генерируют документацию по исходным | ||
+ | кодам.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Наследование кода – Контрол-Ц – | ||
+ | Контрол-В [:]||||||||||||[:]</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Программисты не любят писать | ||
+ | документацию, но теперь есть средства, которые генерируют её | ||
+ | автоматически по комментариям.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">В Обероне от Модулы осталось поняте | ||
+ | Модуля, исчезли списки определений, но появились списки экспорта, и | ||
+ | оставили только один способ импорта – IMPORT. Также отсутствует | ||
+ | понятие главной проргаммы. Считается, что пользователь погружён в ОС, | ||
+ | и модули экспортируют туда себя. Операционная среда Оберон | ||
+ | предоставляет шелл, и пользователь может запускать комманды – | ||
+ | экспортированные функции.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">После педедыва язык Ада.</P> | ||
+ | <P STYLE="margin-bottom: 0cm">//педедыв</P> | ||
+ | <P STYLE="margin-bottom: 0cm">Стиль Си: использование префиксов. Что | ||
+ | делать если имена конфликтуют имена – сплошной геморрой. | ||
+ | Минимум, который необходим – структуризация модулей, хотя бы | ||
+ | один уровень.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Язык Ада представдяет собой | ||
+ | ультимативную модель.</P> | ||
+ | <P STYLE="margin-bottom: 0cm">Есть Пакет – модуль (не путать с | ||
+ | джавой)</P> | ||
+ | <P STYLE="margin-bottom: 0cm">Пакет состоит из</P> | ||
+ | <OL> | ||
+ | <LI><P STYLE="margin-bottom: 0cm">Спецификации пакета</P> | ||
+ | <LI><P STYLE="margin-bottom: 0cm">Тело пакета</P> | ||
+ | </OL> | ||
+ | <P STYLE="margin-bottom: 0cm">package M is</P> | ||
+ | <P STYLE="margin-bottom: 0cm">объявления</P> | ||
+ | <P STYLE="margin-bottom: 0cm">end M;</P> | ||
+ | <P STYLE="margin-bottom: 0cm">package body M is</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">end M;</P> | ||
+ | <P STYLE="margin-bottom: 0cm">Функцию pop на аде написать нельзя, | ||
+ | потому что у адской функции не должно быть побочного эффекта.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">В Аде есть механизм импорта, но он | ||
+ | только для раздельной трансляции.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Импорта как такового нет.</P> | ||
+ | <P STYLE="margin-bottom: 0cm">Есть пакет STANDART. | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Прространства имён могут вкладываться – | ||
+ | коренное отличие от других ЯП.</P> | ||
+ | <P STYLE="margin-bottom: 0cm">Спецификация пакетов – неявный | ||
+ | список экспорта. Доступны они только потенциально. | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Имена пакетов должны быть уникальными.</P> | ||
+ | <P STYLE="margin-bottom: 0cm">Явной конструкции импорта нет, ибо в | ||
+ | других ЯП они нужны для раздельной трансляции. | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Синтаксис: P1.P2. ... .PN</P> | ||
+ | <P STYLE="margin-bottom: 0cm">Интересный вопрос: нужна вложенность | ||
+ | или нет.</P> | ||
+ | <P STYLE="margin-bottom: 0cm">В Аде есть такая штука, как перегрузка | ||
+ | имён и функций, что есть в совр ЯП. Но в Аде можно было также | ||
+ | перкрывать стандартные процедуры и функции, а акже знаки стандартных | ||
+ | операций. Беда в том, что стандартные операции не префиксные | ||
+ | (нектоторые неизвестно какие, например a[i]). Если бы вопрос был | ||
+ | только о префиксных, то вопрос потенциальной видимости не мешает. | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Пусть есть</P> | ||
+ | <P STYLE="margin-bottom: 0cm">package Vectors is</P> | ||
+ | <P STYLE="margin-bottom: 0cm"> type Vector is</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm"> function «+»(x,y:Vector) | ||
+ | return Vector;</P> | ||
+ | <P STYLE="margin-bottom: 0cm">end Vectors;</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">X, Y,Z:Vectors.Vector;</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">X:=Y+z – нельзя</P> | ||
+ | <P STYLE="margin-bottom: 0cm">vectors.«+»(y,z) – | ||
+ | смысл?</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">//программисты, скрипя сердцем... | ||
+ | [:]|||||||||||||||[:]\</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Если попытаться на си написать | ||
+ | A=B*exp(-i*C)*F(x), где всё комплексное, то математик скажет, что это | ||
+ | не язык. Поэтому Страуструп добавил возможность добавления новых | ||
+ | операторов.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">И возникает вопрос, зачем тогда | ||
+ | переопределение операторов если нет непоср области видимости? Поэтому | ||
+ | в Аду есть uses список пакетов. Тогда можно для векторов писать | ||
+ | Z:=X+Y. На первый взгляд всё замечательно. Но что делать, если | ||
+ | возникате конфликт имён? Если X оперделён глобально, в M1, M2. И это | ||
+ | приводит к программам, смысл которых от uses меняектся.</P> | ||
+ | <P STYLE="margin-bottom: 0cm"><BR> | ||
+ | </P> | ||
+ | <P STYLE="margin-bottom: 0cm">Проектирование систем:</P> | ||
+ | <P STYLE="margin-bottom: 0cm">top-down</P> | ||
+ | <P STYLE="margin-bottom: 0cm">bottom-up</P> | ||
+ | <P STYLE="margin-bottom: 0cm">Системы разбиваются на набор модулей, | ||
+ | вопрос в том, с каком порядке разбивать.</P> | ||
+ | <OL> | ||
+ | <LI><P STYLE="margin-bottom: 0cm">Сверху вниз: разбить систему на | ||
+ | модули, эти модули на ещё модули и т. д. Проблема в том, что делают | ||
+ | заглушки. И тут мы тренируемся на лягушатнике, а когда бросают в | ||
+ | бассейн – буль-буль</P> | ||
+ | <LI><P STYLE="margin-bottom: 0cm">Снизу вверх. Модули нижнего уровня | ||
+ | отлаживаются проще. Недостаток: заказчик не знает, что хочет, и | ||
+ | меняет заказ, и видит готовую систему в самый последний момент.</P> | ||
+ | </OL> |
Версия 17:27, 3 февраля 2008
Языки программирования 26.10.06
В прошлый раз мы остановились на межмодульных связях.
Библиотечный модуль Модулы дыва состоит из двух подмодулей, связанных одним именем.:
Модуль-интерфейс, гнде только определения
Модуль-реализация. Реализация и дополн объявления для неё, а так же инициализирующая часть.
Дельфи:
физически представляет собой один модуль, но присутствует понятие ирнтерфейся и реализации, разница чисто синтаксическая. Есть более тонкие моменты, которые отличают, они связаны с механизмом межмодульных связей.
Не разрешаются вложенные моудли.
Возникают два понятия: потенциальная и непоср видимость.
Непосредственна – конгда имя можно употреблять без уточнЯюзей информации
Протенцияалдьная – с уточняющей, указание имени модуля через точку. Везде через точку, только С++ выпендрился, там ::
Непосредственно ыидимыми являются только имена модулей. Все остальные имена потенциально видимые только те, что в разделе определений. Имена из модулей-определений видимы потенциально. Из модуля определений осуществляется экспорт в глобальное пространство имён.
Все имена равноправны.
Кроме понятие экспорта, есть понятие импорта. Импорт может быть как в модуль определений, так и вмоудль реализации. Таблицпа имён из модуля реализаций – конкатенация таблицы из модуля поерделений.
Модуль реализации только импортироет, как из модуля определений (всегда, неявно), так и из других модулей.
Есть две формы импорта:
IMPORT список модулей.
Стандартные и пользовательские модули абсолютно равноправны, при этом реальный ждоступ получаем тогда, когда делуем предожение IMPORT. Оно должно быьб первым среди всех объявлений. С точки зрения реализации компилятор должен просмотреть все папки поиска, и подкачать соотв таблицы имён. При этом соотв имена в этом модуле, если в нём есть предложение IMPORT, все имена из него ст ановятся видимы потенциально. Приходиться писать InOut.WriteLn. Программистов это раздражает, поэтому есть другая формаи импорта: FROM имя модуля IMPORT список идентификаторов – и имена становятся видимы непосредственно. Это сделано в дань программистом, которые ленятся набивать длинные имена. Беда непоср импорта в конфликте имён. Причём могут конфликтовать как с именами других модулей, так и с локальными. Локальные имеют больший приоритет (граждане первого сорта имеют больше прав, относительно иммигрантов). Это достаточно удобная модель.
Отличия Дельфи:
Имена из модульной реализации недоступны никому, но есть едиственная форма предложения импорта: uses список модулей – импорт непосредственный. Если имена конфликтуют между собой, то в этом случае непоср видимост снимается.
С первой точки зрения этот подход более улдобен, но когда лектор столкнулся с программированием в Дельфи и Модуле-2, то на Модуле-2 текст читать приятнее. Ибо когда в uses полтора десятка модулей, то дрогадаться, из какого модуля идентификатор, трудно. Поэтому Борланд всегда поставлял ос всеми своими компиляторами grep. А в Модуле-2 мы обречены на успех при поиске по файлу.
Порядок загрузки модулей поерделяется порядком зависимостей. В момент загрузки доступна инициализация – begin ... end. .
В этих языках есть принцип – РОРИ, Разделение
Определения
Реализация
Использования
Главенствовал в ЯП в 70-ч годах, когда появились ЯП с чёткой модульной структурой.
Есть ли в Си разделение определния и реализации? Это можно сделать, но ручками. И есть много подводных камней. Например, каждый хедер начинается с ifndef, дабы избежать повторного включения модулей.
#ifndef SYMBOL
#define SYMBOL
...
#endif
Интересно с этрой точки зрения посмотреть на язык Оберон, что же он упростил. История идёт по спирали, и там от РОРИ с первого взгляда отказалисб.
В первой версии языка:
DEFINITION M
опр-я
ENDM.
MODULE M
ENDM.
Модно выкинукть понятия модуля определения как такового. Вместо этого можно просто помечать. То же, что и в ассемблере.
MODULE M;
TYPE T* - если после имени стоит звёздочка, то оно экспортируемое
REOCRD
END;
PROCEDURE P* (X:T);
END;
ENDM.
На первый взгляд это отступление от РОРИ. Ибо программисту использующему нужен только интерфейс. На самом деле, в к концу 80-началу 90х годов получил распространение приём, что язык пишется как часть системы программирования.
//На 3 этаже стояли перфораторы
Прграммистдимеет делло с программой, которую просматривает в режиме онлайн.
С этой точки зрения интересен Eifel, который генерировал документирующие модули.
В современных ЯП (Си шарп, Джава) интерфейс и реализация не разделяются. На этот шаг пошли потому, что там есть программы, коотрые генерируют документацию по исходным кодам.
Наследование кода – Контрол-Ц – Контрол-В [:]||||||||||||[:]
Программисты не любят писать документацию, но теперь есть средства, которые генерируют её автоматически по комментариям.
В Обероне от Модулы осталось поняте Модуля, исчезли списки определений, но появились списки экспорта, и оставили только один способ импорта – IMPORT. Также отсутствует понятие главной проргаммы. Считается, что пользователь погружён в ОС, и модули экспортируют туда себя. Операционная среда Оберон предоставляет шелл, и пользователь может запускать комманды – экспортированные функции.
После педедыва язык Ада.
//педедыв
Стиль Си: использование префиксов. Что делать если имена конфликтуют имена – сплошной геморрой. Минимум, который необходим – структуризация модулей, хотя бы один уровень.
Язык Ада представдяет собой ультимативную модель.
Есть Пакет – модуль (не путать с джавой)
Пакет состоит из
Спецификации пакета
Тело пакета
package M is
объявления
end M;
package body M is
end M;
Функцию pop на аде написать нельзя, потому что у адской функции не должно быть побочного эффекта.
В Аде есть механизм импорта, но он только для раздельной трансляции.
Импорта как такового нет.
Есть пакет STANDART.
Прространства имён могут вкладываться – коренное отличие от других ЯП.
Спецификация пакетов – неявный список экспорта. Доступны они только потенциально.
Имена пакетов должны быть уникальными.
Явной конструкции импорта нет, ибо в других ЯП они нужны для раздельной трансляции.
Синтаксис: P1.P2. ... .PN
Интересный вопрос: нужна вложенность или нет.
В Аде есть такая штука, как перегрузка имён и функций, что есть в совр ЯП. Но в Аде можно было также перкрывать стандартные процедуры и функции, а акже знаки стандартных операций. Беда в том, что стандартные операции не префиксные (нектоторые неизвестно какие, например a[i]). Если бы вопрос был только о префиксных, то вопрос потенциальной видимости не мешает.
Пусть есть
package Vectors is
type Vector is
function «+»(x,y:Vector) return Vector;
end Vectors;
X, Y,Z:Vectors.Vector;
X:=Y+z – нельзя
vectors.«+»(y,z) – смысл?
//программисты, скрипя сердцем... [:]|||||||||||||||[:]\
Если попытаться на си написать A=B*exp(-i*C)*F(x), где всё комплексное, то математик скажет, что это не язык. Поэтому Страуструп добавил возможность добавления новых операторов.
И возникает вопрос, зачем тогда переопределение операторов если нет непоср области видимости? Поэтому в Аду есть uses список пакетов. Тогда можно для векторов писать Z:=X+Y. На первый взгляд всё замечательно. Но что делать, если возникате конфликт имён? Если X оперделён глобально, в M1, M2. И это приводит к программам, смысл которых от uses меняектся.
Проектирование систем:
top-down
bottom-up
Системы разбиваются на набор модулей, вопрос в том, с каком порядке разбивать.
Сверху вниз: разбить систему на модули, эти модули на ещё модули и т. д. Проблема в том, что делают заглушки. И тут мы тренируемся на лягушатнике, а когда бросают в бассейн – буль-буль
Снизу вверх. Модули нижнего уровня отлаживаются проще. Недостаток: заказчик не знает, что хочет, и меняет заказ, и видит готовую систему в самый последний момент.