Никлаус Вирт. Заветы смиренного зодчего
Памяти проф. Никлауса Вирта посвящается.
/ Европейский центр программирования им. Леонарда Эйлера, 2024.
/ Руслан Богатырев, 2024.
«Зодчество было главной летописью человечества» / Виктор Гюго /
1. Смирение европейской науки и диктатура американского бизнеса
2. Инженерия зодчества: от железа к софту
3. Этапы большого пути
4. Языки-сундуки и языки-чемоданчики
5. Модульное программирование
6. Расширяемое программирование
7. Три принципа и три закона Никлауса Вирта
Приложение 1. Никлаус Вирт. Мысли и заветы
Приложение 2. Эдсгер Дейкстра. Мысли и заветы
Приложение 3. Избранные книги.
Приложение 4. Избранные статьи.
Приложение 5. Диссертации учеников и последователей Никлауса Вирта
Приложение 6. Избранные интервью (Video)
—
Зодчество… Возвышенное искусство античности. Гармония пространства, порядка и света. Оно зримо преображает мир. Материю вечности камня. Но берёт своё начало в зыбучем песке ментального и эфемерного — во вдохновенном сознании мастера.
Ле Корбюзье, один из выдающихся архитекторов XX века: «Цель строительства — компоновать элементы. Цель зодчества — двигать нас вперёд».
В искусстве архитектуры, насчитывающем не одно тысячелетие, есть свои каноны знания, свои фолианты священных книг:
• Марк Витрувий. Десять книг об архитектуре (13 г. до н. э.).
• Леон Батиста Альберти. Десять книг о зодчестве (1485).
• Андреа Палладио. Четыре книги об архитектуре (1570).
В искусстве компьютерного программирования, пока не насчитывающем и одного века, подобные капитальные труды ещё ждут своего часа и своих авторов. Впрочем, рискну назвать список фундаментальной и нетленной классики:
• Дональд Кнут. Искусство программирования (1968).
• У. Дал, Э. Дейкстра, Ч. Хоар. Структурное программирование (1972).
• Эдсгер Дейкстра. Дисциплина программирования (1976).
• Никлаус Вирт. Алгоритмы и структуры данных (1976).
• Никлаус Вирт. Построение компиляторов (1996).
В области компьютерных наук и информационных технологий (computing) есть свой Пантеон. Своя галерея великих. Своя Нобелевка. Пусть и в американской упаковке (ACM). Если мы взглянем на этот почётный список лауреатов премии Алана Тьюринга (The ACM A.M.Turing Award, 1966-2022), то заметим, что среди 76 фамилий избранных — 83% представляют Северную Америку (63 человека), 16% — Европу (12 человек) и 1% — Азию (единственный представитель).
Выделим создателей языков программирования (в хронологическом порядке присвоения премии Тьюринга) — Эдсгер Дейкстра (1972, Algol-60), Кеннет Айверсон (1979, APL), Деннис Ритчи (1983, C), Никлаус Вирт (1984, Euler, Algol-W, Pascal, Modula-2, Oberon), Батлер Лэмпсон (1992, Mesa, Cedar), Оле-Йохан Дал (2001, Simula и Simula-67), Кристен Нюгард (2001, Simula и Simula-67), Алан Кей (2003, Smalltalk), Петер Наур (2005, Algol-60), Барбара Лисков (2008, CLU).
Здесь уже пропорции между представителями Америки (5) и Европы (5) соблюдены.
== 1. Смирение европейской науки и диктатура американского бизнеса
Если говорить начистоту, Америка в компьютерной сфере давно уже подмяла науку под бизнес. Причём хоронила её методично. Свидетельства этого можно найти в архиве работ Эдсгера Дейкстры. Остроумного и беспощадного в своей иронии критика: Карла Маркса и Марка Твена компьютерного программирования в одном лице.
Он неоднократно подчёркивал принципиальные различия между европейской вычислительной наукой (computing science) и американской компьютерной наукой (computer science), между информатикой (informatics) и компьютингом (computing). Жёстко противопоставлял разные культурные традиции Европы и Америки: науку — бизнесу, математику — машинам, мысль — наживе: «Вычислительная наука имеет не большее отношение к компьютерам, чем астрономия — к телескопам».
Дейкстра был до глубины души поражён соглашательской позицией научной интеллигенции: «Многие правительства заставляли свои университеты сотрудничать с промышленностью… В результате даже гениальный исследовательский потенциал должен был направляться на нечто недолговечное, мелкое или глупое». Ему претила рабская зависимость высшего образования от пропитанного жаждой наживы бизнеса: «Чтобы университет был лидером, он должен предлагать то, в чём общество нуждается, а не то, что оно запрашивает». Дейкстра был против того, чтобы приспосабливать программирование к неграмотности и посредственности. По его мнению, это не только унижает достоинство профессии, но и вредит делу.
Близким другом и соратником Эдсгера Дейкстры в беспощадной борьбе с диктатурой сложности и наживы был Никлаус Вирт. Оба приезжали в нашу страну: Дейкстра — в 1976 г. (Москва, Ленинград, Киев, Новосибирск), а Вирт — в 1990, 1996 и 2005 гг.
Причём Большое турне Вирта в 2005 г., организованное по просьбе его ближайшего сподвижника проф. Юрга Гуткнехта (ETH Zurich) и приуроченное к 250-летию МГУ им. М. В. Ломоносова, а также юбилеям языков Вирта (Pascal, Modula-2, Oberon), по своей географии стало рекордным (Москва, С.-Петербург, Нижний Новгород, Екатеринбург, Новосибирск, Томск). Основную координацию осуществляли Р. П. Богатырёв («Мир ПК») и Ф. В. Ткачёв (Институт ядерных исследований РАН). Существенную помощь в реализации этого масштабного проекта оказали проф. А. А. Шалыто (С.-Петербург, ИТМО), проф. В. А. Сухомлин (Москва, МГУ), проф. В. П. Гергель (Нижний Новгород, ННГУ), Е. А. Зуев (ETH Zurich), Э. М. Пройдаков (PC Week/RE), А. Е. Недоря и В. Э. Филиппов (Новосибирск, Институт систем информатики им. А. П. Ершова РАН). По итогам Большого турне Никлауса Вирта и был образован Европейский центр программирования им. Леонарда Эйлера.
В Советском Союзе были сильны приоритеты и традиции европейской школы программирования. Три её ярких представителя — Эдсгер Дейкстра (Нидерланды), Энтони Хоар (Великобритания) и Никлаус Вирт (Швейцария) — составляли ключевой триумвират. На них равнялись. Их изучали. Глубоко.
Неудивительно, что в наших университетах и научных центрах акцент делался на сам фундамент зодчества программирования — на трансляторы и языки. Именно эта наукоёмкая сфера была центральной в работах Никлауса Вирта.
Вернёмся к мудрым суждениям французского архитектора Ле Корбюзье: «Необходимо понимать историю. Ведь тот, кто её понимает, знает, как найти связь между тем, что было, тем, что есть, и тем, что будет».
—
Небольшой исторический экскурс. Лирическое отступление. Возвращение к первоистокам приоритета научной мысли.
В середине XX века центрами зарождения компьютерной жизни были ведущие страны: США, Советский Союз, Великобритания, Германия. Затем уже от работ в этих сверхдержавах пошли волны влияния по всему миру.
Не секрет, что Советский Союз славился не только балетом, хоккеем, фигурным катанием и шахматами, но и своими достижениями в науке и передовых технологиях: авиация, космонавтика, атомная энергетика, военная сфера. Качество инженерной подготовки кадров опиралось на сильные традиции и на мобилизационную экономику 1930–1960 годов. У нас готовились не просто инженерные кадры. Готовились инженеры-математики. Именно русская и советская математическая школа вкупе с колоссальными прорывами в области физики и химии обеспечивали тогда интеллектуальное мировое лидерство Советского Союза. Его индустриальную и военную мощь. Вершинами научных и технологических достижений стали атомный проект (академик И. В. Курчатов) и космический проект (академик С. П. Королёв). Не последнюю роль сыграл так и не оформившийся окончательно кибернетический проект (академик В. М. Глушков).
Если вести отсчёт от Петра I и от основанной им в Москве школы «математических и навигацких, то есть мореходно хитростно искусств учения» (Школа Пушкарского приказа, 1701), следует признать, что математика в России зарождалась не ради голых абстракций, не для составления кадастра землевладений, а ради ключевых задач военного искусства. Необходимых для выживания страны.
Полагаю, в наши дни уже излишне объяснять, что такое программирование. Под этим понятием чаще подразумевается компьютерное программирование (computer programming). Хотя в незапамятные времена гораздо больший акцент делался на то, что теперь называют математическим программированием (mathematical programming). Это отражает и трансформацию приоритетов: сначала говорили о математическом обеспечении компьютеров (ЭВМ), потом — исключительно о программном обеспечении.
Первичным в те годы было железо, компьютеры. Ибо единично, дорого и недоступно. Вторичным — расчётные и управляющие программы (софт). Сначала приоритет отдавался науке, учёным (европейская школа). Затем — бизнесу, инженерам (американская школа). Примерно до 1965 г. в Штатах сами компьютеры физически специализировались под обе ветви: наука (военные расчёты) и экономика (банки и корпорации).
Что было главным катализатором развития на заре компьютерной техники в середине прошлого века? Правильно: военная сфера. Причём горячая, а не холодная. В самом разгаре.
Вспомним первый американский универсальный компьютер ENIAC (1943-1945). Для чего он создавался? Расчёты задач баллистики. Кто заказывал и финансировал? Лаборатория баллистических исследований армии США (BRL, The Ballistic Research Laboratory; U.S. Army). Кто решал поставленную задачу? Пенсильванский университет (Джон Эккерт, Джон Мокли).
Лаборатория баллистических исследований… Весьма нерядовая организация. В её Научный консультативный совет входили выдающиеся учёные и инженеры:
- Альберт Халл (физик, президент Американского физического общества, отец магнетрона);
- Бернард Льюис (химик, один из основателей Института горения, The Combustion Institute);
- Хью Драйден (руководитель разработки первой самонаводящейся планирующей бомбы ASM-N-2 Bat; после войны — директор по авиационным исследованиям NАСA, предшественницы NASA);
- Генри Рассел (астрофизик, директор астрономической обсерватории Принстонского университета, автор одной из первых теорий эволюции звёзд);
- Исидор Раби (физик, лауреат Нобелевской премии по физике 1944 г. за резонансный метод измерений магнитных свойств атомных ядер, зам. директора Лаборатории излучений в MIT; после войны — один из основателей швейцарского Центра ядерных исследований CERN);
- Гарольд Юри (физик и химик, лауреат Нобелевской премии по химии 1934 г. за исследование изотопов и открытие дейтерия, один из лидеров Манхэттенского проекта по разработке ядерного оружия в США, курировал секретные работы по обогащению урана);
- Джон фон Нейман (математик, участник Манхэттенского проекта, автор одной из первых архитектур компьютеров, один из разработчиков математического аппарата квантовой механики, создатель теории игр и клеточных автоматов).
На ENIAC Джон фон Нейман работал над расчётами сжатия плутониевого заряда до критической массы, а также над расчётами по проблеме создания термоядерной бомбы.
Вслед за ENIAC в США почти сразу же появился EDVAC. Всё та же Лаборатория баллистических исследований. Всё тот же Джон фон Нейман.
Разумеется, помимо поставленных американцами на пьедестал компьютерного пантеона ENIAC и EDVAC были и чисто экспериментальные разработки первых компьютеров. Реального вклада в военную сферу они не внесли. Но разработки были. Среди них Z3 (1941) немецкого инженера Конрада Цузе, автора и первого языка программирования высокого уровня (Планкалкюль, 1948). В этом ряду пионеров компьютеростроения стоит упомянуть также Джона Атанасова и Клиффорда Берри (Atanasoff-Berry Computer, ABC, 1942).
Были и варианты узкоспециализированных военных компьютеров. Среди них, пожалуй, самой теперь известной является английская «Бомба Тьюринга» (Turing Bombe математика Алана Тьюринга). Первое устройство для вскрытия военных шифров (немецкой криптомашины «Энигма»). В Великобритании в годы Второй мировой войны большую роль сыграл секретный проект Ultra (вскрытие шифров Lorenz SZ 40/42, Hagelin, Purple, JN-25). Помимо этого немалый вклад в решении всё тех же криптографических задач внёс английский дешифровальный компьютер Colossus (1943) Томми Флауэрса и Макса Ньюмана.
В Советском Союзе первые специализированные аналоговые компьютеры появились в предвоенные и военные годы. В частности, стоит упомянуть одномерный гидравлический интегратор ИГ-1 Владимира Сергеевича Лукьянова (1936, дифференциальные уравнения в частных производных) и разработку Сергея Алексеевича Лебедева (1945, обыкновенные дифференциальные уравнения). Всё та же военная тематика. А первым в континентальной Европе универсальным цифровым компьютером стал МЭСМ (Малая электронная счётная машина, 1948-1950) академика С. А. Лебедева, директора Института точной механики и вычислительной техники (ИТМиВТ) Академии наук СССР.
В отношении неутихающих споров вокруг первенства между МЭСМ (С. А. Лебедева) и М-1 (И. С. Брука). Формальный повод — разница в 10 дней между актами приёмки.
Первая программа С. Г. Крейна и С. А. Авраменко, решающая задачу баллистики, успешно была реализована на МЭСМ осенью 1951 г. Через год после начала работ по комплексной отладке МЭСМ. Об этом свидетельствуют воспоминания Л. Н. Дашевского и Е. А. Шкабара («Как это начиналось», 1981). Лев Наумович Дашевский в ту пору занимал пост заместителя заведующего лабораторией, возглавляемой С. А. Лебедевым. В декабре 1951 г. комплексная отладка МЭСМ (работы над которой были инициированы в конце 1947 г.) была завершена и начались испытания на задачах, которые готовили сотрудники Института математики Академии наук УССР.
В конце 1951 г. из Москвы приехала комиссия АН СССР. Именно она и осуществляла приёмку. Возглавлял комиссию академик М. В. Келдыш (в 1961 г. он станет президентом АН СССР). В её состав входили выдающие советские математики — академики АН СССР С. Л. Соболев и М. А. Лаврентьев. Решение комиссии: принять МЭСМ с 25 декабря 1951 г. в эксплуатацию.
Что касается М-1, т. е. чисто исследовательской работы в Энергетическом институте АН СССР, который занимался созданием и развитием Единой энергетической системы СССР и который возглавлял академик и вице-президент АН СССР Г. М. Кржижановский, то 15 декабря 1951 г. сподвижник Ленина действительно утвердил отчёт по работе «Автоматическая цифровая вычислительная машина». Никакой приёмки и внешней комиссии, тем более от АН СССР, не было. Сами задумали, сами сделали, сами приняли.
== 2. Инженерия зодчества: от железа к софту
Какое отношение этот исторический экскурс имеет к Никлаусу Вирту? Самое непосредственное.
Эдсгер Дейкстра и Никлаус Вирт были технарями и отлично знали то, поверх чего и на чём конкретно работают создаваемые программы. Напомню, что Дейкстра в 1956 г. окончил факультет теоретической физики Лейденского университета (Universiteit Leiden), старейшего в Нидерландах. Он досконально знал мэйнфрейм Electrologica X8, на котором реализовывал свою знаменитую операционную систему THE OS (1965-1968), а также изучил всю линейку компьютеров Burroughs (B5000/B5500/B6500/B6700/B7700). В Burroughs Corporation Эдсгер Дейкстра проработал с 1973 по 1984 гг.
Никлаус Вирт окончил в 1954 г. факультет электроники в ETH Zurich (по специальности electrical engineering). С раннего детства его увлекала сложная техника — поезда, самолёты, авиамоделизм. В 1949 г. он даже выступал в Великобритании за национальную команду Швейцарии в международных соревнованиях по авиамоделизму. Новейшая английская электроника для дистанционного управления моделями была для него мощным стимулом для интеллектуального развития.
Вспоминаю, как он восторгался богатейшей коллекцией советской авиационной техники, представленной в Центральном музее ВВС в Монино, куда в сентябре 2005 г. его и Юрга Гуткнехта удалось отвезти на масштабную экскурсию. Никлаус Вирт стоял у истоков беспилотной авиации. Неудивительно, что его языки помимо автоматизации Швейцарских федеральных железных дорог (SBB-CFF-FFS) активно использовались для разработки бортового программного обеспечения как наших спутников (Modula-2; «Информационные спутниковые системы им. академика М. Ф. Решетнёва», Красноярск), так и некоторых моделей БПЛА.
В стенах ETH Zurich он имел доступ к немецким компьютерам Z4 и Z11 Конрада Цузе. В Университете Калифорнии в Беркли работал на американском компьютере Bendix G-15, созданном под влиянием британского ACE (Automatic Computing Engine) Алана Тьюринга. В Стэнфордском университете основным у него был мэйнфрейм IBM System/360, на котором экспериментировал с языком и компилятором Algol-W.
Будучи блестящим знатоком современных промышленных и исследовательских компьютеров и процессорных архитектур с середины 1970-х годов проф. Вирт начал создавать собственное железо: так появились 16-разрядный настольный компьютер Lilith (Modula-2, Medos, процессор AMD2901 компании Advanced MicroDevices) и 32-разрядная рабочая станция Ceres (Oberon, Oberon System, процессор NS32032 компании National Semiconductor). Компьютер Lilith в Советском Союзе послужил прототипом, основой разработки 32-разрядного семейства Kronos (Modula-2, операционная система Excelsior). Работы велись во второй половине 1980-х годов в Новосибирском Академгородке (ВЦ СО АН СССР) под руководством В. Е. Котова. Ведущие разработчики: Д. Н. Кузнецов, А. Е. Недоря, Е. В. Тарасов, В. Э. Филиппов. На основе работ этого коллектива в 1990 г. был образован Институт систем информатики им. А. П. Ершова СО РАН (ИСИ СО РАН). В 2005 г. свой личный экземпляр Lilith Никлаус Вирт передал в дар Политехническому музею. А. Е. Недоря и В. Э. Филиппов подарили музею рабочую станцию «Кронос-2.6WS». Причём именно тот экземпляр, который в НПО ПМ им. М. Ф. Решетнёва использовался в 1990-х годах в качестве инструментальной машины для создания бортового программного обеспечения для российских спутников. Другие экземпляры отечественного технологического чуда находятся теперь в стенах Музея науки в Лондоне (Science Museum), в Музее Сибирского отделения РАН, в НГУ и в ИСИ СО РАН.
Никлаус Вирт не боялся всё делать с нуля. Невольно вспоминается недостижимый ныне универсализм титанов классической музыки: Иоганн Себастьян Бах был не только гениальным композитором, непревзойдённым архитектором выверенных музыкальных конструкций, вдохновенным капельмейстером, виртуозным органистом, но и своими руками создавал и настраивал установленные в немецких готических храмах гигантские органы.
Приведу небольшую выдержку из книги известного советского математика, одного из зачинателей отечественного программирования Александра Семёновича Кронрода «Беседы о программировании» (1963). Она во многом разъясняет скрытую мотивацию проф. Вирта: «Пусть нам нужно выкопать большой канал. С чего стоит начать? Первое, что приходит в голову, — взять лопаты и копать. И, если не думать, что можно построить экскаватор, то чем скорее возьмешь лопату и чем энергичнее станешь ею действовать, — тем быстрее и глубже будет твоя канава. Ну, а если поверить, что экскаватор построить всё-таки можно? Тогда, пожалуй, стоит повременить с лопатой. И как можно энергичнее заняться экскаватором. Особенно, если копать лопатой и строить экскаватор должны одни и те же люди. И, конечно, если канава не нужна немедленно и непосредственно, во имя спасения жизни».
Раз уж зашла речь о генезисе, о корнях ментальности Никлауса Вирта, стоит привести здесь и краткую биографическую справку.
Его альма-матер — Высшая Политехническая школа ETH Zurich, где учились Альберт Эйнштейн (1896) и Джон фон Нейман (1923). Именно туда он поступил на факультет электроники в 1954 г. Далее после получения степени бакалавра (electrical engineering) — в 1958 г. переезд по совету отца в Канаду, в Лавальский университет Квебека, где становится магистром. Научную карьеру (PhD, язык Euler) продолжил в университете Калифорнии в Беркли (1960-1963) под руководством Гарри Хаски, сподвижника Алана Тьюринга по созданию компьютера ACE. Затем работал доцентом в Стэнфордском университете (1963-1967), где дорабатывал Euler и создавал язык Algol-W, после чего вернулся в 1967 г. в родную Швейцарию и основал там свою школу программирования в стенах ETH. Долгие годы возглавлял Институт компьютерных систем при ETH. Оставался профессором ETH вплоть до 1999 г.
Среди учителей и наставников Никлауса Вирта — президент международной ассоциации IFIP Амброз Спайзер (Ambros Speiser) в ETH Zurich (Швейцария), президент американской ассоциации ACM Гарри Хаски (Harry Huskey) в University of California, Berkeley (США), а также директор Mathematisch Centrum Адриан ван Вейнгаарден (Aadrian van Wijngaarden) в University of Amsterdam (Нидерланды).
Важную роль в разработке его языков сыграли научные стажировки в Xerox Palo Alto Research Center (Xerox PARC): 1976-1977 (Modula-2 под влиянием Mesa) и 1984-1985 (Oberon под влиянием Cedar). Весьма продуктивным оказалось и его сотрудничество с IBM Zurich Research Laboratory (Мартин Рейзер).
Вспомним доминантные универсальные языки программирования и те компании, которые вносили решающий вклад в их продвижение: Fortran (IBM), PL/I (IBM), Basic (Microsoft), Pascal (Borland), C++ (Microsoft), Java (Sun Microsystems), C# (Microsoft). Особняком стоит язык C. Он проникал в индустрию через разные диалекты UNIX, его продвигали на рынок сразу несколько компаний и здесь трудно кому-то отдать предпочтение.
Мир науки и мир бизнеса активно пересекались и сталкивались. Но интересы их всё больше расходились. Переломным в программировании стал 1968 г. На конференции NATO по программной инженерии в Гармиш-Партенкирхене (Германия) в октябре 1968 г. Фридрих Бауэр, профессор Технического университета Мюнхена, ввёл в обиход термин «кризис программного обеспечения». Его подхватил и Эдсгер Дейкстра. Спустя несколько лет вовсю заговорили о программировании в малом (programming-in-the-small) и программировании в большом (programming-in-the-large).
Это переосмысление сути программирования неизбежно отразилось и на языках. При этом академизм стал всё чаще противопоставляться прагматизму.
Никлаус Вирт заложил традицию присвоения языкам программирования имён выдающихся математиков прошлого. В 1963 г. он дал имя Леонарда Эйлера, великого швейцарского математика, основателя русской математической школы, своему первому творению — языку Euler. А в 1970 г. Блез Паскаль, великий французский математик и философ, творчеством которого восхищались Н. Г. Чернышевский и Л. Н. Толстой, был увековечен проф. Виртом в языке Pascal.
Язык Euler (1963) — расширение и обобщение языка Algol-60, поддерживающее динамическую типизацию. Это одно из ранних архитектурных творений Никлауса Вирта, которым так восхищался Алан Кей, отец-основатель объектно-ориентированного программирования (ООП), автор языка и системы Smalltalk. Сам же Вирт спустя годы сдержанно-скептически относился к своему творению. И похоже считал его тупиковой ветвью в своей научной карьере. Что вполне объяснимо выбранными приоритетами — смиренный классицизм программной архитектуры, контроль инженерной надёжности для проф. Вирта куда важнее кружевной барочности фонтанирующего произвола безудержной мысли. Именно смиренный классицизм позволяет эффективно бороться с всё возрастающей сложностью.
В 2005 г. мне довелось пообщаться с Леоном Кацнельсоном, директором IBM по конкурентным технологиям при департаменте информационного управления. Тогда я упомянул о работе Пола Хорна (главный вице-президент IBM Research) по автономному компьютингу. В ней высказывается следующая мысль: сложность современных ИТ-систем — это серьёзный вызов. Как это ни парадоксально, чтобы избежать сложности, утверждает Хорн, надо делать ещё более сложные системы. Т. е. сложность преодолевается через сложность. Хорн подчёркивает, что следуя принципам автономного компьютинга, надо системы ещё более усложнять, но внедрять при этом элементы адаптивности. Кацнельсон отреагировал на мысль Хорна весьма дипломатично, сохранив парадоксальность: «Чем сложнее система, тем больше необходимость её упрощать. При этом сам процесс упрощения ещё больше усложняет эти системы».
Очевидно, что надо искать золотую середину. И не менее очевидно, что всё отдавать здесь во власть человеку — не выход. Человеческий фактор чаще провоцирует сложность, поскольку человек привык идти по пути наименьшего сопротивления.
Если кратко обозначить ключевые вехи пути Никлауса Вирта, они выглядят так:
1. 1970. Pascal — структурное программирование (structured programming).
2. 1979. Modula-2 — модульное программирование (modular programming).
3. 1988. Oberon — расширяемое программирование (extensible programming).
На каждом последующем витке эволюции происходило критическое редуцирование исходного ядра, языка-предшественника (изъятие лишнего) и привнесение ровно одной ключевой новой конструкции: это были модуль (module) в Modula-2 и расширение типа (type extension) в Oberon.
Описание языков также эволюционировало в сторону лаконичности: Pascal (50 стр.), Modula-2 (40), Oberon (16).
Самым известным достижением проф. Вирта считается язык Pascal (1970). Безусловно, многие об этом языке слышали и знают его. Pascal сыграл огромную роль в области формирования мировоззрения нескольких поколений программистов. Главное его достоинство в простоте и элегантности: он построен на чётких принципах структурного программирования, сформулированных Эдсгером Дейкстрой, на красивой математической базе, заложенной Энтони Хоаром, и на блестящем архитектурном воплощении идей Algol-W (1966), реализованных Никлаусом Виртом. С технологической точки зрения, Паскаль был интересен не только тем, что его компилятор, созданный в ETH Zurich, стал одной из первых реализаций языков высокого уровня на самом себе, примерно на два года опередив компилятор C. В ходе работ над ним в 1973 г. была придумана абстрактная Pascal-машина (P-машина), исполняющая специальный P-код. Чтобы решить проблему переноса компилятора языка Pascal на разные платформы, Вирт решил воспользоваться испытанными временем методами интерпретации. Из наиболее известных решений, предшествовавших P-коду, можно назвать реализацию языка Snobol-4 (Р. Грисуолд, 1967), где в качестве кода абстрактной машины использовался язык SIL (System Implementation Language).
Язык Modula-2 (1979) был не только компактной и эффективной альтернативой языку Ada. Он намного опережал те реализации идей модульного программирования, которые лишь спустя годы и в гораздо менее продуманном виде нашли своё отражение в Turbo Pascal и Delphi (и в так и не выпущенной на рынок системе программирования Turbo Modula-2, трансформировавшейся в JPI Modula-2). Знаменитая операционная система OS/400 для IBM AS/400 была реализована на Modula-2. Центр системных исследований корпорации Digital (DEC Systems Research Center) взял этот язык в качестве основы реализации своих внутренних проектов, создав впоследствии язык Modula-3.
Подлинной жемчужиной архитектурного творчества Никлауса Вирта стал проект Oberon (1988). Расширяемая операционная система Oberon (Oberon System), созданная одновременно с языком Oberon, играла в начале 1990-х — конце 2000-х годов примерно такую же роль, что играли в 1980-х годах проекты Alto и Xerox Star знаменитого центра Xerox PARC, откуда пошли современные персональные компьютеры и текстовые редакторы. Для таких корпораций, как IBM, Microsoft и Sun Microsystems, проект Oberon стал источником плодотворных идей, среди которых можно выделить документо-ориентированный интерфейс, браузеры, промышленные языки разработки ПО (Java и C#), машинно-независимый мобильный код (JVM и .NET CLR), аплеты, компонентное ПО, динамическую компиляцию (JIT, AOC, DAC), смарт-теги, веб-службы и др.
Проф. Вирт с гордостью сообщал, что компилятор языка Oberon для рабочей станции Ceres реализован на языке Oberon. Он состоит из 6 модулей общим размером около 4 тыс. строк исходного текста, требует менее 50 Кбайт памяти и сам себя компилирует за 15 сек. на процессоре NS32532 (25 МГц). Впечатляет.
Системе Oberon предшествовали исследования, которые проводились в ETH в 1981–1985 гг. на Lilith Юргом Гуткнехтом и его коллегами, Вернером Винигером и Шером. Сначала появился редактор Andra с поддержкой всевозможных окон, шрифтов, средств композиции страницы, а затем и редактор Lara. Примерно в тот же период проф. Вирт разработал графический редактор и завершил работы над новым однопроходным компилятором языка Modula-2.
К середине 1988 г. уже был готов компилятор для экспериментальной рабочей станции Ceres-2 (на базе NS-32532) и прошли первые публикации проф. Вирта (в апреле и июле; сначала «Type Extensions» в ACM Transactions on Programming Languages and Systems, а затем «From Modula to Oberon» в Software Practice & Experience). Вторая стадия проекта Oberon наступила летом 1991 г., когда было положено начало так называемой Oberon System 3.
«Перечислить все идеи, на основе которых сформировалось то, что сегодня называется Oberon, — писал Вирт, — просто нет возможности. Большинство этих идей родилось в ходе применения или изучения существующих языков (таких, как Modula-2, Ada, Smalltalk, Cedar), которые часто показывали нам, каких решений следует избегать».
Силы в ETH Zurich в 1990-е годы были сосредоточены на создании переносимых и перенацеливаемых компиляторов для разных платформ. Этим занимались преимущественно аспиранты Никлауса Вирта и Юрга Гуткнехта. К февралю 1990 г. был готов переносимый компилятор OP2. Кстати, именно его брали за основу при начале работ над компилятором Oberon-2 Алексей Недоря и его новосибирские коллеги по XDS. В июне 1989 г. доцент ETH Ханспетер Мёссенбок (Hanspeter Mössenböck) спроектировал Object Oberon, добавив ООП-расширения в канонический Oberon. Именно Мёссенбока, пожалуй, и следует считать автором Oberon-2, в который вылился Object Oberon. Проф. Вирт не возражал против соавторства в языке, поскольку расхождения по сравнению с Oberon были не фатальными. Хотя и не лежали в рамках того критического взгляда на ООП, который исповедовал сам Вирт. Весной 1991 г. в журнале Structured Programming (издательство Springer-Verlag, в редколлегии были Н. Вирт и Д. Кнут) в одном номере вышли две статьи, давшие публичную жизнь языку Oberon-2: «The Programming Language Oberon-2» и «Differences between Oberon and Oberon-2», под которыми стояли фамилии Мёссенбока и Вирта. К моменту появления Oberon-2 в 1991 г. информация о языке Oberon только-только стала выходить из стен ETH. Сторонние разработчики компиляторов сделали ставку именно на Oberon-2, считая, что это просто улучшенный Oberon.
В 1993 г. в ETH Zurich приехали представители Sun Microsystems во главе с Биллом Джоем. Они приобрели лицензию на систему Oberon и пригласили с ответным визитом выступить у них лучших учеников Вирта — Микаэль Франц сразу после защиты соответствующей диссертации в ETH делал доклад по динамической кодогенерации в Sun Labs в марте 1994 г., за 14 месяцев до выхода Java и за полгода до разработки браузера HotJava.
Франц так это прокомментировал (1996): «Согласно информации Sun [JavaSoft], идея переориентации Java на World Wide Web возникла в 1994 г. и принадлежала Биллу Джою, одному из основателей фирмы. Осенью 1994 г. началась работа по реализации web-браузера HotJava с возможностью выполнения аплетов. В марте 1995 г. браузер был представлен избранному кругу стратегических партнеров Sun, включая руководство корпорации Netscape Communications, чья публичная поддержка впоследствии немало способствовала успеху новой технологии. В августе 1995 г. состоялся триумфальный выпуск Java, который происходил в довольно необычной для базовых технологий форме — в виде серии пресс-конференций. Быть может, интересно то обстоятельство, что в марте 1994 г. автором был прочитан в Калифорнии ряд докладов по теме диссертации, причём один из них — в Sun Laboratories, Inc. Кроме того, упомянутый выше Билл Джой, который переориентировал проект Java на WWW, стал одним из первых обладателей лицензии на Oberon System из ETH, и в конце 1994 — начале 1995 г. он неоднократно связывался с ETH; в процессе контактов выяснилось, что он читал мою диссертацию».
В 1994 г. Микаэль Франц, разрабатывавший ранее кодогенератор Оберона для MC680×0 (Macintosh), завершил работу над кодогенератором в промежуточный код — OMI (Oberon Module Interchange). Впервые на русском языке информация об этом была опубликована в альманахе «Технология программирования» (1995, № 1). Идея Франца была проста — вместо традиционной схемы «компилятор — компоновщик — загрузчик» получить схему «компилятор — кодогенерирующий загрузчик», иными словами, совместить генерацию кода, компоновщик и загрузчик в одном флаконе.
Концепция «code-generation on-the-fly» (динамическая кодогенерация) с использованием компактного древовидного представления вместо классического байт-кода была положена в основу одноимённой диссертации М. Франца, которую он защищал в ETH Zurich в феврале 1994 г. Его научными руководителями были Никлаус Вирт и Юрг Гуткнехт. Крайне интересная диссертация. Редкий случай — в Цюрихе в марте 1994 г. она была переиздана в виде книги.
В Sun не рискнули сразу копировать всё из Oberon (идеи браузерной среды языка, аплетов и трансляции в мобильный код взяли, а вот путь реализации мобильного кода выбрали свой). В 1991 г. автор Java Джеймс Гослинг при реализации Oak (прототипа языка Java) взял старую идею P-кода Никлауса Вирта, которую хорошо знал: в 1975 г. Гослинг вместе с Недом Китлицем и Бобом Сайдботемом участвовал в построении среды программирования Pyxis/Multics Pascal, способной по быстродействию кода и удобству интеграции на равных конкурировать в Multics c родным для этой ОС языком PL/I. А начинали они с поддержки компилятора ETH Zurich Pascal, разработанного в Цюрихе группой профессора Вирта. В 1979 г. Гослинг реализовал PERQ — транслятор с P-кода в машинный код 32-разрядной DEC VAX.
В 1994 г. Sun не стали сразу включать новейшую хитроумную реализацию мобильного кода в древовидном представлении, которую предлагал в своей диссертации Франц, а сохранили готовый подход Гослинга. Для всей отрасли модель Sun на долгие годы стала эталоном. А Микаэль Франц уехал в Калифорнию (University of California, Irvine) и в настоящее время является ведущим американским экспертом по JIT-компиляции и мобильному коду.
Осенью 1997 г. Игорь Васильевич Поттосин, директор Института систем информатики Сибирского отделения РАН, сподвижник академика А. П. Ершова, переслал мне очень интересное письмо Никлауса Вирта, которое во многом повлияло на моё мировосприятие. Но сначала поясню ситуацию. В июньском номере журнала IEEE Computer (1997) вышла необычная статья под названием «The Feel of Java». Это, кстати, ведущее издание профессиональной ассоциации IEEE Computer Society. Приведу цитату.
≪ Java — это настоящий язык-трудяга. Это не результат чьей-то диссертации, это язык для работы. Java покажется очень знакомым самым разным программистам, поскольку мы предпочитаем делать проверенные вещи. Итак, что же такое Java? Java ощущаешь как игривый и гибкий язык. Вы можете создавать с его помощью такие вещи, которые сами являются гибкими. Java ощущаешь как детерминированный язык. Если вам хочется, чтобы он что-то сделал, просто попросите его об этом. В нём не видится ничего опасного: вы можете спокойно попробовать что-то сделать, и если окажетесь неправы, то быстро получите сообщение об ошибке. Java ощущаешь как очень богатый язык. Мы постарались снабдить его большой библиотекой классов. Поэтому не откладывайте дело в долгий ящик, а садитесь за компьютер и пишите свой код. ≫
Не складывается ли впечатление, что перед нами выдержка из рекламного объявления? А ведь эти слова принадлежат Джеймсу Гослингу, не только автору Java, но и человеку, который защитил диссертацию в известном университете Карнеги-Меллон, связанную с проектом Andrew Windows System, и который в те годы стал вице-президентом компании Sun Microsystems.
«Представьте себе, — не в силах сдержать возмущение, комментирует приведённую цитату проф. Вирт, — что эти слова были написаны в 1960-е годы, и замените слово «Java» на слово «Алгол». Автора сочли бы человеком психически ненормальным, слова его большей частью чужды науке и не имеют с ней ничего общего. Сегодня никто даже не возмущается. Нет никакой реакции от «научного» сообщества. Как же низко могла пасть компьютерная наука? И это делается с молчаливого одобрения такой уважаемой организации, как IEEE Computer Society?»
== 4. Языки-сундуки и языки-чемоданчики
Oberon славится своей простотой и концептуальной сбалансированностью. Но его простота сложна. Сложна для тех, кто привык сложность перекладывать со своих плеч на чужие (с прагматики языка на его семантику). Язык C++ представляет собой пример иного подхода — попытки убрать сложность путём введения многочисленных инструментов. Но при этом вместо одной проблемы возникают другие: сложность переносится на иной уровень и становится нередко неконтролируемой — количество связей между базовыми сущностями и структурами (включёнными в семантику языка) начинает возрастать, они вступают в явные и неявные конфликты, распутывать которые должен будет тот, кто этот язык применяет.
Проф. Вирт в языке Oberon шёл вполне понятным путём. Сначала выбирается область применения инструмента (цели): системное программирование применительно к разработке операционной системы Oberon (однопользовательская ОС класса Developer’s OS), в которой главными требованиями являются динамическая расширяемость систем (extensible programming) при изолированности (герметичности) системы типов. Затем используется принцип концептуальной экономии (по Энтони Хоару): проф. Вирт брал сбалансированный набор базовых сущностей и их отношений (связей, правил — моделью была классическая Modula-2) и удалял из языка (синтаксиса и семантики) те вещи, которые не разрушали исходные цели. Иными словами, искал ту грань, за которой система (в данном случае язык Oberon) будет оптимизирована по критерию концептуальной экономии и не рассыплется. Этой цели он добился. Для реализации системы Oberon (Oberon System) язык Oberon выглядит близким к идеалу.
Теперь посмотрим на C++. Цели, которые ставил перед собой Бьёрн Страуструп, существенно отличались от целей, поставленных Виртом перед языком Oberon. Страуструп хотел, с одной стороны, воплотить идеи своего любимого языка (Simula-67), оставаясь на базе синтаксиса (и семантики!) языка C. Т.е. обеспечить преемственность. И в этом плане с Виртом они не сильно расходятся (преемственность по синтаксису и семантике у Oberon с Modula-2 даже куда выше, чем у C и C++). А вот с другой — он хотел создать объёмный универсальный самодостаточный язык, который может практически всё. Поиск пресловутого философского камня.
Проблема Страуструпа была в другом — он хотел насытить язык многими полезными вещами. А каков в этом случае критерий развития языка? Почему можно прямо в язык (не в библиотеки) добавить одну полезную вещь и не добавлять другую? У Вирта удаление «лишней» полезной вещи приводит к рассыпанию системы. Нарушает ортогональность базиса. У Страуструпа добавление «лишней» вещи не рассматривается как разрушение системы, поскольку система (язык) воспринимается сама по себе в отрыве от того, кто ею оперирует (и кто хранит в своей голове полезные и вредные связи между плодящимися сущностями языка). В этом и есть главная проблема подобных языков, стремящихся вобрать в себя побольше всякого полезного. Нет сдерживающего фактора, кроме чувства меры (а больше вкусовщины) комитета по стандартизации (уже не самого Страуструпа, мнение которого здесь далеко не решающее). К чему ведёт такой подход? К неконтролируемому росту сложности как самого инструмента, так и сферы его практического применения.
Если кто-то пытается применять систему (язык Oberon) вне той задачи, для которой она предназначалась и оптимизировалась, то следует задуматься: виноват инструмент, его автор или же тот, кто, не понимая инструмента, пытается его применять где можно и где нельзя. Oberon — это язык-ядро, язык-чемоданчик. Это не язык-оболочка, не язык-сундук. Для использования в области промышленного производства программного обеспечения, промышленной разработки сложных программных систем, характеризующейся разделением труда при наличии большого числа программистов, классический Oberon требует соответствующей инфраструктуры (как, скажем, его диалект — Component Pascal и инструментальная система BlackBox), не отвергающей, а впитывающей в себя дополняющие языки (в их синтаксических одеждах). Только в этом случае он, пожалуй, будет адекватен решаемым задачам в этой сфере. В качестве иллюстрации к сказанному хотел бы напомнить слова великого немецкого философа Иммануила Канта, которые нам не стоит забывать: «Кто отказался от излишеств, тот избавился от лишений».
Языки-сундуки и языки-чемоданчики... Интересная метафора проф. В. Ш. Кауфмана (МГУ). Думаю, имеет смысл сделать ещё одно небольшое отступление и ввести читателя в контекст обсуждения. Очень рекомендую тем, кто серьёзно интересуется вопросами зодчества языков и их концепций, перечитать блестящий курс В. Ш. Кауфмана «Языки программирования. Концепции и принципы» (1993). Этот курс читался на факультете вычислительной математики и кибернетики МГУ. Проф. Кауфман пишет: «Безнадёжно строить языки программирования с моделями, заготовленным «на все случаи жизни». Однако можно попытаться построить язык программирования, на базе которого будет удобно (относительно несложно, с приемлемыми затратами) строить модели весьма разнообразных проблемных областей. Такой язык называют базовым языком программирования… Главное назначение базового языка — строить модели проблемных областей с тем, чтобы уменьшить сложность программирования в них. На примере Ады мы видели, как выявляемые технологические потребности приводили к новым конструктам. Может показаться, что на этом пути будут получаться всё более качественные языки программирования. К сожалению, большинство современных индустриальных языков программирования носят на себе родимые пятна такого примитивного критерия качества… Основной принцип конструирования, которым руководствовались авторы этих языков программирования, в упрощённой форме можно сформулировать так: для каждой значимой в проблемной области технологической потребности в языке должно быть готовое выразительное средство. Короче: каждой значимой потребности — новый конструкт. Этот принцип заготовленности конструктов и назовём принципом сундука (именно в сундуках хранят много всякого на всякий случай). Как показывает опыт, безудержное применение принципа сундука ведёт к громоздким, сложным, дорогим в реализации, обучении и использовании языкам-монстрам с тяжеловесным базисом и несбалансированными средствами развития… Никлаус Вирт неоднократно отмечал, что самое трудное при создании языка программирования — решить, от чего следует отказаться. Объясняя принципы конструирования своего (теперь уже предпоследнего) языка Modula-2 (поразившего специалистов элегантностью), Вирт развил эту идею и сформулировал следующий принцип языкового минимума: в язык программирования следует включать такие концепты и конструкты, без которых совершенно невозможно обойтись. Назовём этот принцип минимума принципом чемоданчика по контрасту с принципом сундука (в чемоданчик кладут только абсолютно необходимое)».
Проф. Вирт, на мой взгляд, верно нащупал стиль классицизма в развитии инструментария. В то время как все, увлекаясь архитектурой барокко, помчались насыщать языки всё новыми могучими средствами и переносить центр тяжести на графические среды, он понял, что идти надо в противоположном направлении. Вычленяя квинтэссенцию и вынося за рамки компетенции данного языка паразитную нагрузку. Это напоминает выделение в наборе команд процессора базового минимума, из которого строится остальное (RISC), напоминает идею микроядра ОС, напоминает Forth-системы… Микроядро — один из важных принципов создания программных и технических систем.
Oberon — это удачный вариант микроядерного языка традиционного императивного программирования, ориентированного на самую распространённую процессорную модель Эккерта-Неймана. Другим языком-микроядром можно назвать классический C. Отличительной особенностью Oberon является сбалансированность языка, опирающаяся на принцип концептуальной экономии и внутреннюю ортогональность: механизм расширения типов (type extension), обобщение процедур (процедурные типы), концепция модуля.
Вообще говоря, число языков-ядер (не обязательно микроядер) существенно меньше общего числа языков, но тем не менее языки-ядра представляют возможности выбора с учётом исповедуемого ими понятийного пространства. В дополнение к упомянутым Oberon и C можно отметить классику (а не современные вариации): Lisp, Рефал, Prolog, Forth, Smalltalk, Pascal, Occam.
== 5. Модульное программирование
Исторически сложилось так, что модульное программирование в своём классическом понимании оказалось для большинства программистов землёй неизведанной, terra incognita. Из ведущих языков программирования на начало 2000 гг., пожалуй, только Delphi (со времён Turbo Pascal 4.x) имеет средства (unit), отдалённо приближённые к классике. Концепция модуля, кстати, отсутствует в таких известных языках, как Smalltalk-80 и Eiffel.
Как же так произошло? Дело в том, что доминирующая сейчас ветвь языков C-семейства (C, C++, Java, C#) не опиралась на эту концепцию, вытеснив её в конце 1980-х годов другой, возведённой в разряд абсолюта — объектно-ориентированным программированием (ООП). Туда же рванул и модный интерпретируемый Python.
Кстати, по состоянию на февраль 2024 г. в рейтинге TIOBE Index первая пятёрка популярных языков программирования выглядит именно так: Python (15,16%), C (10,97%), C++ (10,53%), Java (8,88%), C# (7,53%). Эти лидеры в сумме контролируют 53,07% всего корпуса интереса аудитории. На удивление, Modula-2 даже входит в Топ-100 рейтинга TIOBE. Чего нельзя сказать о Pascal и Oberon. Впрочем, диалект Delphi/Object Pascal в текущем рейтинге занимает 12-ю позицию (1,40%).
Если предельно упрощать, ООП опирается на идею совмещения в концепции класса (class) понятий модуля (module), типа (type) и механизма расширения (extension; наследования, обогащения). При этом в рамках ООП на основе классов непросто добиться полноценного воплощения возможностей триады «модуль-тип-расширение», исповедуемой, в частности, языками Oberon-семейства. Приходится добавлять понятие пространства имён (namespace), охватывающее вместо одного несколько файлов, да ещё и с поддержкой вложенности, вводить вместо понятного механизма экспорта-импорта запутанный набор средств по разграничению областей видимости (public, private, friend, protected и т. п.).
Модуль можно сравнить с устройством, имеющим средства сопряжения (подключения), через которые и происходит как управление самим устройством, так и обмен данными. Это своего рода чёрный ящик, для которого экспорт и импорт определяют его интерфейс и зависимость от других устройств.
Принципиальное отличие модулей от классов: модули — это уникальные экземпляры (второго такого в системе нет), не допускающие обобщения (generic-модули здесь не рассматриваем, они находятся вне подхода Вирта и в его языках не поддерживаются). Т.е. на их основе ничего порождать нельзя.
Модули не только определяют чёткие синтаксические границы кода (процедур) и данных, но также являются единицами этапа компиляции (unit of compilation) и единицами этапа загрузки (а также выполнения, замены — unit of replacement). Эти единицы можно редактировать, документировать, распространять и компилировать по отдельности. В модульном программировании связывание происходит на этапе загрузки (динамическое связывание, dynamic linking) и абсолютно невидимо пользователю.
Модуль — это контейнер для набора объектов, при этом он является средством абстрагирования кода и данных, ибо имеет две части: интерфейс (definition) и реализацию (implementation). Целостность данных и их защита обеспечивается в модулях за счёт сокрытия информации (information hiding, или инкапсуляции) и физического вычленения данных и кода из создаваемой системы (программы). Причём при сочленении модулей гарантируется соблюдение всех требований безопасности типов (type safety).
Интерфейс в модульном программировании рассматривается как жёсткая спецификация, контракт, который должен неукоснительно соблюдаться клиентами модуля (импортирующими его) и реализацией данного модуля (или несколькими альтернативными реализациями). Любое изменение контракта требует перекомпиляции всех зависимых модулей. Стоит отметить, что компилятор языка Oberon в системе ETH Oberon поддерживает режим расширения интерфейса, когда чистое расширение (добавление процедур) не влияет на ранее оттранслированные модули. В этом случае создаётся расширение бинарного представления интерфейса (символьного файла), что позволяет подстыковывать расширенную версию модуля без перекомпиляции ранее оттранслированных клиентских модулей.
Для модульного программирования характерно использование раздельной компиляции (separate compilation), когда компиляция интерфейса и реализации модуля делается отдельно от реализации других модулей, но с обязательным участием интерфейсов всех прямо и косвенно импортируемых модулей.
Высокая гибкость в модульном программировании достигается за счёт совмещения фазы компоновки и загрузки. А в некоторых случаях (реализация Oberon на уровне подхода Oberon Module Interchange, предложенного Микаэлем Францем в 1994 г.) совмещается на этом этапе (перед компоновкой) и фаза генерирования машинного кода для конкретной целевой архитектуры (то, что впоследствии после выхода Oberon получило распространение как JIT-компиляция).
Модуль (и его данные) существует всё то время, пока загружен в память. Область его видимости регулируется средствами явного экспорта-импорта идентификаторов (импорта модулей; экспорта процедур, типов, констант, переменных, отдельных полей составных переменных).
Инициализация всех модулей, затрагиваемых данной программой, производится в порядке, обратном их глубине зависимости по импорту. Другими словами, перед началом работы программы производится т. н. топологическая сортировка, которая позволяет выявить последовательность проведения инициализации в направлении от абсолютно независимых по импорту модулей к максимально зависимым.
Модуль на уровне своего содержимого устанавливает важный принцип No Paranoia Rule. Иными словами, внутри одного модуля можно размещать несколько классов, при этом общение между их полями и методами абсолютно прозрачно внутри, тогда как снаружи может регулироваться средствами избирательного экспорта (т.е. спецификаторами экспорта). Схема инкапсуляции в одном модуле строго одного класса практически соответствует общепринятой модели ООП. Иными словами, программист волен выбирать степень концентрации нескольких классов в одном модуле. Это важное преимущество классического Oberon по сравнению с другими языками ООП.
В языке Modula-2 для получения возможностей тонкого управления экспортом-импортом на локальном уровне (в рамках программных и исполнительных модулей) Вирт ввёл понятие локального модуля. Однако практика показала, что это излишний и запутанный механизм, который в языке Oberon был уже исключён.
В системе Oberon появилось весьма интересное решение, связанное с модульным программированием. Понятие программы исчезло. Вместо этого проф. Вирт ввёл концепцию команд (command). Команды — это экспортируемые процедуры без параметров, определяющие точки входа (вызова) программы. Другими словами, программа превратилась в модуль, экспортирующий по сути сервисы. В Oberon System команды становятся полноправными командами операционной системы, которые можно напрямую запускать, связывать в последовательность обработки и т. п. Любые модули (библиотечные и программные — разницы между ними нет) можно динамически загружать и выгружать (без перекомпиляции).
Чтобы детальнее разобраться в природе модульного программирования, центрального в философии проф. Вирта, давайте обратимся к истории.
До начала 1970-х годов программы создавались в виде монолитных блоков, либо делались из независимых частей, сопряжение которых было достаточно примитивным — на уровне вызовов подпрограмм (процедур). Отсюда и пошли два известных понятия — целостная компиляция (whole compilation) и независимая компиляция (independent compilation). Первый случай простой и пояснений наверняка не требует (транслируется вся программа целиком). Во втором каждый блок (файл) транслируется отдельно, фактически без наличия информации о точках сопряжения. Все проблемы увязки возлагались на компоновщик (linker). Именно он состыковывал оттранслированные части, соединял программу с библиотеками, которые та использовала.
Лобовое решение этой проблемы нашло своё отражение в языке C в виде знаменитых директив препроцессора (#include). Здесь проблема не решалась, а запрятывалась вглубь. Вместо строгого контроля и чёткого взаимодействия механизмов экспорта-импорта, выделения областей видимости и существования предлагалось использовать сокращённую запись операций скрытого расширения исходного текста на этапе, непосредственно предшествующем компиляции (препроцессинга).
Не буду вдаваться в подробности относительно проблем директивы #include, унаследованных другими языками C-семейства, особенно C++. Об этом написано предостаточно. См. напр., P.Moylan «The Case Against C» (1992), M. Sakkinen «The Darker Side of C++» (1992), I.Joyner «C++? A Critique of C++ and Programming and Language Trends of the 1990s» (1996).
В каноническом Pascal (в трактовке Вирта) данный вопрос вообще никак не решался, и это было безусловно ахиллесовой пятой языка. Но в конце 1970-х годов сразу три языка включили в свой арсенал эффективный механизм модуля. Это сделали CLU (1973, Барбара Лисков, Массачусетский технологический институт, США) — понятие кластера (cluster), Modula-2 (1979, Никлаус Вирт, ETH Zurich) — понятие модуля (module) и Ada (Джин Ихбиа и др., 1980, Министерство обороны США) — понятие пакета (package).
Однако, пожалуй, первым наиболее явно это сделал язык Mesa (1973, Джеймс Митчелл и др., Xerox PARC), — язык, положенный Виртом в основу Modula (1976), а потом и Modula-2 (1979) после года работы Никлауса Вирта (1976-1977) в стенах Xerox PARC.
Всем этим языкам предшествовали научные исследования, отчёты о которых выходили в очень компактный промежуток времени (1971-1974).
Сначала в апреле 1971 г. в Communications of the ACM появилась статья Никлауса Вирта «Разработка программ методом пошагового уточнения» (Niklaus Wirth «Program Development by Stepwise Refinement»). В ней не использовалось слово «модуль», но при этом на примере классической задачи по расстановке 8 ферзей на шахматной доске были сформулированы подходы к декомпозиции (разбиению) монолитной программы на набор задач (действий, инструкций), каждая из которых при очередном шаге уточнения получает всё более высокую степень конкретизации, при этом затрагивая конкретизацию и данных. Это устанавливало иерархию абстракций на уровне операций и данных.
В декабре 1972 г. в Communications of the ACM была опубликована статья Дэвида Парнаса из университета Карнеги-Меллон «О критериях по декомпозиции систем на модули» (David Parnas «On the Criteria To Be Used in Decomposing Systems into Modules»).
Помимо собственно декомпозиции системы важным критерием модуляризации Парнас назвал сокрытие информации (information hiding, «скрывать решение от других»). За счёт использования средств внешних модулей (слова «использует», «зависит от») формируется иерархическая структура, которая задаёт отношение частичного порядка, подразумевающего проведение топологической сортировки.
В работе «A History of CLU» Барбара Лисков (Barbara Liskov) из Массачусетского технологического института вспоминает: «В 1972 г. я предложила идею разделов (partitions). Система делится на иерархию разделов, каждый из которых представляет один уровень абстракции и состоит из одной или нескольких функций, оперирующих общими ресурсами… Связь на уровне данных между разделами ограничена использованием явных аргументов, передаваемых из функций одного раздела во (внешние) функции другого раздела. Неявное взаимодействие с общими данными осуществляется только среди функций, лежащих внутри соответствующего раздела…»
Далее она продолжает: «Это привело меня к пониманию связывания модулей с типами данных и к идее абстрактных типов, имеющих инкапсулированное представление и операции, которые могут быть использованы для доступа и манипулирования объектами… Я называла типы абстрактными, поскольку они не предоставляются напрямую языком программирования, а вместо этого должны реализовываться пользователем. Абстрактный тип является абстрактным точно в таком же смысле, как-то, что процедура является абстрактной операцией».
В начале 1973 г. Барбара Лисков на фоне разочарования работами по методологии программирования и зачатками модульного программирования в развитие идеи разделов создала новую концепцию — кластер (cluster), что и привело к образованию нового языка — CLU.
Концепция модуля как основы сокрытия информации (information hiding) тесно переплелась с концепцией абстрактных типов данных (ADT, abstract data types), поскольку введение различных уровней абстракции и обеспечивалось средствами контроля областей видимости со стороны модуля.
В октябре 1974 г. вышла статья Тони Хоара «Monitor: An Operating System Structuring Concept». Годом ранее в работе «Operating System Principles» Пер Бринч Хансен ввёл аналогичное понятие «shared». Впоследствии этой идее дали название мониторы Хансена-Хоара. Это особая форма модуля, в который заключены процедуры и соответствующие структуры данных, при этом доступ к модулю (его процедурам) для внешних процессов является взаимоисключающим.
Таким образом, к середине 1970-х годов понятие модуля стало обретать всё более ясные очертания, при этом сформировались две специфики его применения — мультипрограммирование (монитор) и абстрактные типы данных (кластер). Всё это нашло отражение в языке Modula-2, где роль мониторов выполняли модули с приоритетами (в них реализовывались драйверы устройств), а абстрактные типы данных воплощались в понятии скрытых типов (opaque type). Последние на уровне описательного модуля (DEFINITION MODULE) выглядели простым названием без объявления структуры, а на уровне исполнительного модуля (IMPLEMENTATION MODULE) реализовывались, как правило, указателями на запись (RECORD). В языке Oberon мониторы, как и другие средства мультипрограммирования Modula-2, вынесены за пределы языка, а абстрактные типы данных реализуются средствами частичного (избирательного) экспорта.
== 6. Расширяемое программирование
Прежде всего, следует сказать, что расширяемое программирование (extensible programming) является симбиозом модульного программирования и ООП, направленным на создание расширяемых программных компонентов.
Предположим, что у нас есть некоторое программное устройство/приспособление (плеер, калькулятор, текстовый редактор и т. п.). Запрограммирована и отлажена логика его работы. Управление осуществляется через интерфейс, на который опираются другие (внешние) устройства/приспособления.
Допустим, что в ходе эксплуатации нашего устройства выявились некоторые нюансы, которые требуют введения дополнительных ручек управления (для тонкой настройки, индикации режимов, адаптации к особенностям использования и т. п.). Встаёт задача такого расширения функционала устройства, при котором не потребовалось бы вносить изменения в зависящие от него устройства. Более того, в идеале хотелось бы подменить «на лету» старый вариант устройства на его расширенный вариант.
Как быть? Oberon даёт простой и эффективный ответ на подобный вопрос: функционал данного устройства можно расширять бесшовно путём добавления в интерфейс новых процедур, при этом не затрагивая другие устройства (без их перекомпиляции) и без использования какого бы то ни было ООП. Это достигается за счёт средств раздельной компиляции, использующих понятие основного и расширенного интерфейса.
Остаётся добавить, что весь этот процесс осуществляется в режиме жёсткого контроля соответствия интерфейсов по экспорту/импорту на уровне языка программирования со статической типизацией (т.е. Oberon) и что подобные устройства (компоненты), характеризующиеся длительным временем жизни (persistence), в системе Oberon System 3 (ETH Oberon) называются словом gadget (приспособление).
Почему для таких задач расширяемое программирование (включающее в себя в случае надобности и средства ООП) лучше подходит, нежели традиционное ООП на основе классов? Как известно, любое специальное устройство можно реализовать эффективнее соответствующего универсального. И если нет необходимости жертвовать эффективностью и надёжностью во имя пресловутой универсальности, то выбор всегда будет в пользу специализации.
Расширяемое программирование в трактовке классического Oberon выступает в двух разновидностях: расширение в большом, т. е. на уровне модулей (о котором говорилось выше), и расширение в малом, на уровне типов данных (type extension). Если учесть, что класс в языке Oberon трактуется как расширяемый тип, заключённый внутрь модуля, то нетрудно сделать вывод, что подобная схема (варьирования специализацией/универсализацией) более надёжна и одновременно более гибка, нежели традиционное промышленное ООП.
Никлаус Вирт: «Я бы не стал говорить, что распространившаяся практика ООП реализовала весь свой потенциал. Наша конечная цель — расширяемое программирование (extensible programming). Под этим я понимаю возможность конструирования таких иерархий модулей, когда каждый добавляет в систему новую функциональность. Расширяемое программирование подразумевает, что можно добавлять модуль без необходимости вносить какие-либо изменения в существующие модули — не должно быть даже необходимости их перекомпилировать».
== 7. Три принципа и три закона Никлауса Вирта
В живописи, в зодчестве, в программировании действует один и тот же закон мироздания, прекрасно сформулированный Ильёй Ефимовичем Репиным: «Сначала художник рисует просто и плохо. Потом сложно и плохо. Потом сложно и хорошо. И только потом — просто и хорошо». Путь от свободного творчества к ремеслу и далее — к настоящему искусству.
Да, подробное и развёрнутое изложение любого вопроса помогает вникнуть в детали, разобраться в нюансах, уловить полутона. Но нередко куда более действенной и полезной становится простая и краткая формулировка. В виде постулатов, принципов, законов.
Итак, вот три фундаментальных принципа Никлауса Вирта:
1. Минимум языковых средств важнее их максимума (язык-ядро против языка-оболочки).
2. Первичность материализма базовых концепций (расширяемое модульное программирование против ООП).
3. Простота последующего чтения куда важнее лёгкости исходного написания (художественная эстетика программного текста: Pascal-синтаксис против C-синтаксиса).
• Вирт. Первый закон: Простые и элегантные решения более эффективны, но их труднее найти, чем сложные, и они требуют больше времени, чем-то, что мы готовы на это потратить.
• Вирт. Второй закон: Порочный круг. Преподаватели не могут изменить свои курсы, т. к. они должны доставить удовольствие студентам. Студенты требуют то, что практикуется в промышленности. А индустрия применяет и воспроизводит то, чему обучены еë кадры.
• Вирт. Третий закон: Сложность способствует поддержанию зависимости потребителя от поставщика. Зависимость клиента более доходна, чем его обучение.
И для сопоставления — три закона Паркинсона и три закона Дейкстры.
—
• Паркинсон. Первый закон: Работа заполняет всё время, доступное для её завершения.
• Паркинсон. Второй закон: Расходы растут вместе с доходами.
• Паркинсон. Третий закон: Рост означает сложность, а сложность — это гниение и тлен.
—
• Дейкстра. Первый закон: Тестирование программ может показать наличие ошибок, но никогда не покажет их отсутствие.
• Дейкстра. Второй закон: Если отладка — процесс удаления ошибок, то программирование должно быть процессом их внесения.
• Дейкстра. Третий закон: Искусство программирования — это искусство организации сложности.
—
В заключение вспомним, как завершал в 1972 г. свою тьюринговую лекцию «Смиренный программист» (The Humble Programmer) Эдсгер Дейкстра: «Мы будем лучше справляться с нашей работой в программировании, если только сможем подходить к ней с полным осознанием её потрясающей сложности. Если будем верны строгим и элегантным языкам программирования. Если будем осознавать всю природную ограниченность нашего ума и приниматься за работу как очень смиренные программисты».
В 1986 г. при подготовке той лекции к новому изданию Дейкстра отмечал: «Задача программирования — это интеллектуальный вызов высочайшего ранга. Меня поражает то обстоятельство, что и по сей день актуальность не исчезла. По-прежнему основная трудность в том, как не заблудиться в тех сложностях, что мы сами себе создаём… Есть какая-то верхняя грань скорости, с которой общество в состоянии усваивать прогресс. И мне ещё нужно учиться быть более терпеливым».
Приложение 1. Никлаус Вирт. Мысли и заветы
MODULE W1. ИСТИНА И ЗАБЛУЖДЕНИЯ / Wirth.Verity
• Люди ошибочно воспринимают сложность как виртуозность. Непостижимое должно вызывать подозрение, а не восхищение.
• Перед нами в высшей степени устойчивый порочный круг: преподаватели не могут изменить свои курсы, т. к. они должны доставить удовольствие студентам. Студенты требуют то, что практикуется в промышленности. А индустрия применяет и воспроизводит то, чему обучены еë кадры.
• Истинные проблемы разработки программного обеспечения связаны не с отсутствием инструментов или надлежащего менеджмента, а в значительной степени с отсутствием достаточной технической компетентности.
• Программирование является, возможно, самой важной новой дисциплиной постиндустриальной эры.
MODULE W2. СЛОЖНОСТЬ И ПРОСТОТА / Wirth.Simplicity
• Сложность привлекала и будет привлекать многих людей. Да, мы живём в сложном мире и стремимся решать сложные по своей сути проблемы, которые часто требуют сложных методов. Однако это не должно подавлять нашего стремления к элегантным решениям, которые убеждают своей ясностью и действенностью. Простые и элегантные решения более эффективны, но их труднее найти, чем сложные, и они требуют больше времени, чем-то, что мы готовы на это потратить.
• Как можно научиться хорошему и эффективному проектированию, если базовый формализм, само основание представляет собой ошеломляющую, непостижимую путаницу?
• То, что я был преподавателем, оказало решающее влияние на то, чтобы сделать язык и системы максимально простыми. Чтобы потом в преподавании я мог сосредоточиться на основных вопросах программирования, а не на деталях языка и нотации.
• Когда мощность системы измеряется числом её возможностей, количество становится более важным, чем качество.
• Вряд ли мы лучше справляемся с вопросами сложности на уровне аппаратного обеспечения, чем на уровне программного.
• Компьютерные и программные системы стали безмерно сложными не столько потому, что все их чудесные средства и возможности были на самом деле нужны, сколько просто потому, что они были возможны.
• Сложность способствует поддержанию зависимости потребителя от поставщика… Зависимость клиента более доходна, чем его обучение.
MODULE W3. ЛЮДИ И ИНСТРУМЕНТЫ / Wirth.Engineering
• Посмотрим правде в глаза: разве большинство учреждений образования не оказалось заложниками горстки компаний, чья профессиональная цель состоит в повышении доходов?
• Многие считают, что язык программирования — всего лишь код, единственное назначение которого состоит в конструировании программного обеспечения, выполняемого на компьютерах. Однако язык программирования — это модель вычислений, а программы — это формальные тексты, к которым применимы математические рассуждения.
• Наследники Паскаля, существенно его превосходившие, Modula-2 и Oberon, не получили должного внимания среди преподавателей и сами пали перед лицом самого недостойного из соперников — C. Самого недостойного, т. к. в этом языке были нарушены все открытые к тому времени принципы серьёзного программирования. Только за одни эти пороки он заслуживает изгнания из учреждений образования. Однако сей уродливый синтаксис был целиком воспроизведён в языке Java, принятие которого академическим сообществом произошло отчасти благодаря этой преемственности.
• Модульность — решающее свойство, позволяющее сочетать противоречивые требования: обеспечение надёжности абстракции высокого уровня через проверку на избыточность и наличие низкоуровневых средств, обеспечивающих доступ к индивидуальным конструктивным особенностям конкретного компьютера.
• Постоянный недостаток времени — вот первейшая причина, приводящая к появлению громоздкого программного обеспечения… Дефицит времени подрывает инженерные стандарты качества и совершенства. Спешка оказывает пагубное воздействие как на персонал, так и на разрабатываемые продукты.
• Тенденция принимать первый появившийся продукт в качестве стандарта de facto — крайне прискорбный феномен, вызванный к жизни всё той же спешкой.
• Следующие два «закона» чрезвычайно хорошо (хотя и с долей иронии) отражают нынешнее положение дел:
1) Программное обеспечение увеличивается в размерах до тех пор, пока не заполнит всю доступную на данный момент память (Сирил Паркинсон).
2) Программное обеспечение тормозится куда быстрее, нежели ускоряется аппаратура (Мартин Рейзер, IBM Zurich Research Laboratory).
• Лучше всего учиться, что-то изобретая.
• Достижения измеряются размером команды, количеством публикаций, цитирований и докладов на конференциях, а также использованными ресурсами — но никак не преданностью делу преподавания, которую все равно невозможно измерить. Разумеется, такой стиль академической жизни нередко противоречит внутренним убеждениям индивидуума, но навязывается давлением извне превратить храмы знаний в хорошо разрекламированные источники доходов, и этот стиль граничит с проституцией.
• Тщательная инженерная работа не приносит дивидендов в лихорадочной гонке на короткие дистанции.
• В действительности язык характеризуется не столько тем, что даёт нам возможность программировать, сколько тем, что удерживает нас от использования недопустимых конструкций.
Приложение 2. Эдсгер Дейкстра. Мысли и заветы
MODULE D1. ИСТИНА И ЗАБЛУЖДЕНИЯ / Dijkstra.Verity
• Вычислительная наука (computing science) имеет не большее отношение к компьютерам, чем астрономия — к телескопам.
• Чтобы университет был лидером, он должен предлагать то, в чём общество нуждается, а не то, что оно запрашивает.
• Опыт никоим образом автоматически не приводит к мудрости и пониманию.
• Я был поражён восприимчивостью — я бы сказал даже беззащитностью русских перед иностранным (преимущественно американским) влиянием.
• Бессмысленно пытаться убедить мир исправиться, пока этот мир всё ещё убежден, что он на правильном пути.
• Проекты, предлагающие программирование на естественном языке, гибельны по своей сути.
• Попытки использовать компьютеры для имитации человеческого разума всегда казались мне довольно глупыми. Я бы предпочёл использовать их, чтобы имитировать что-то получше.
MODULE D2. СЛОЖНОСТЬ И ПРОСТОТА / Dijkstra.Simplicity
• Мы являемся свидетелями массового, повсеместного распространения полного ошибок программного обеспечения, из-за чего нам должно быть очень стыдно… Мы просто не знаем, до какой степени можно всё упростить.
• Настало время сорвать маску с компьютерного сообщества — Тайного общества по созданию и сохранению искусственной сложности.
• Простота является предпосылкой надёжности.
• Простота — великое достоинство, но требуется упорный труд для её достижения и образование для её осознания. Увы, сложность продаётся лучше.
• Искусство программирования — это искусство организации сложности.
MODULE D3. ЛЮДИ И ИНСТРУМЕНТЫ / Dijkstra.Engineering
• Помимо математической подготовки исключительно хорошее владение родным языком является самым важным активом компетентного программиста.
• Тестирование программ может оказать наличие ошибок, но никогда не покажет их отсутствие.
• Если отладка — процесс удаления ошибок, то программирование должно быть процессом их внесения.
• Средства не виноваты в том, что их используют безграмотно.
• Студентов, ранее изучавших BASIC, практически невозможно обучить хорошему программированию. Как потенциальные программисты они подверглись необратимой умственной деградации.
• Программирование на COBOL калечит мозг. Поэтому обучение ему должно трактоваться как преступление.
• Мы все сформированы инструментами, которые мы используем: формальные системы и языки формируют наши мыслительные привычки — хорошие или плохие. Это означает, что мы должны быть очень осторожными в выборе того, что мы изучаем и чему учим. Отучиться уже невозможно.
• Слишком мало людей понимают, что высокие технологии, которые сегодня так прославляются, по сути являются технологией математической.
1. Niklaus Wirth. Systematic Programming: An Introduction / Prentice-Hall, 1973.
2. Niklaus Wirth. PASCAL User Manual and Report / Springer, 1974.
3. Niklaus Wirth. Algorithms + Data Structures = Programs / Prentice-Hall, 1976.
4. Niklaus Wirth. Programming in Modula-2 / Springer, 1982. @
5. Niklaus Wirth. Algorithms & Data Structures / Prentice-Hall, 1985.
6. Niklaus Wirth. Modula-2 / Prentice Hall, 1990.
7. Martin Reiser. The Oberon System: User Guide and Programmer's Manual / Addison-Wesley, 1991.
8. Niklaus Wirth, Jürg Gutknecht. Project Oberon: The Design of an Operating System and Compiler / Addison-Wesley, ACM Press, 1992.
9. Martin Reiser, Niklaus Wirth. Programming in Oberon: Steps Beyond Pascal and Modula / Addison-Wesley, ACM Press, 1992.
10. Niklaus Wirth. Digital Circuit Design for Computer Science Students / Springer, 1995. @
11. Niklaus Wirth. Compiler Construction / Addison-Wesley, 1996.
12. Andre Fischer and Hannes Marais. The Oberon Companion. A Guide to Using and Programming Oberon System 3 / ETH Zurich, 1997.
13. Niklaus Wirth. Algorithms and Data Structures (in Oberon) / ETH Zurich, 2004.
14. Niklaus Wirth. Programming in Oberon / ETH Zurich, 2004.
1. Никлаус Вирт. Систематическое программирование. Введение / М. : Мир, 1977.
2. К. Йенсен, Никлаус Вирт. Паскаль. Руководство для пользователя и описание языка / М. : Финансы и статистика, 1982.
3. Никлаус Вирт. Алгоритмы + структуры данных = программы / М. : Мир, 1985.
4. Никлаус Вирт. Программирование на языке Модула-2 / М. : Мир, 1987.
5. Никлаус Вирт. Алгоритмы и структуры данных / М. : Мир, 1989.
6. Никлаус Вирт. Алгоритмы и структуры данных / СПб. : Невский диалект, 2001.
7. Никлаус Вирт. Алгоритмы и структуры данных. Новая версия для Оберона + CD / М. : ДМК Пресс, 2010. @
8. Никлаус Вирт. Построение компиляторов / М. : ДМК Пресс, 2010.
9. Никлаус Вирт, Юрг Гуткнехт. Разработка операционной системы и компилятора. Проект Оберон / М. : ДМК Пресс, 2012.
Приложение 4. Избранные статьи
H. D. Huskey, Ralph Love, Niklaus Wirth. A syntactic description of BC NELIAC // Communications of the ACM, Volume 6, Issue 7 / July 1963.
Niklaus Wirth. A generalization of ALGOL // Communications of the ACM (CACM), Volume 6, Issue 9 / September 1963.
Niklaus Wirth. A proposal on string manipulation within ALGOL 60 // ALGOL Bulletin (ALGOL), Issue 17 / July 1964.
George E. Forsythe, Niklaus Wirth. Automatic grading programs // Communications of the ACM (CACM), Volume 8, Issue 5 / May 1965.
Niklaus Wirth. A Programming Language for the 360 Computers // Stanford University, Computer Science Department, December 1965.
Niklaus Wirth, Helmut Weber. EULER: a generalization of ALGOL, and its formal definition: Part I // Communications of the ACM (CACM), Volume 9, Issue 1 / January 1966.
Niklaus Wirth, Helmut Weber. EULER: a generalization of ALGOL, and its formal definition: Part II // Communications of the ACM (CACM), Volume 9, Issue 2 / February 1966.
Niklaus Wirth, C.A.R. Hoare. A contribution to the development of ALGOL // Communications of the ACM (CACM), Volume 9, Issue 6 / June 1966.
Niklaus Wirth. A Programming Language for the 360 Computers // Stanford University, Computer Science Department, December 1966.
Niklaus Wirth. On Certain Basic Concepts of Programming Languages // Stanford University, Computer Science Department, May 1967.
Niklaus Wirth. PL360, a Programming Language for the 360 Computers // Journal of the ACM (JACM), Volume 15, Issue 1 / January 1968.
Niklaus Wirth. Closing word at Zurich Colloquium // ALGOL Bulletin (ALGOL), Issue 29 / November, 1968.
Niklaus Wirth. On multiprogramming, machine coding, and computer organization // Communications of the ACM (CACM), Volume 12, Issue 9 / September 1969.
Niklaus Wirth. The Programming Language Pascal // Acta Informatica, Vol. 1, No. 1 / January 1971.
Niklaus Wirth. Program development by stepwise refinement // Communications of the ACM (CACM), Volume 14, Issue 4 / April 1971.
Niklaus Wirth. The Programming Language Pascal (Revised Report) // ETH Zurich, November 1972.
C. A. R. Hoare, Niklaus Wirth. An Axiomatic Definition of the Programming Language Pascal // ETH Zurich, November 1972.
Niklaus Wirth. On the Composition of Well-Structured Programs // ACM Computing Surveys (CSUR), Volume 6, Issue 4 / December 1974.
Niklaus Wirth. An assessment of the programming language PASCAL // Proceedings of the international conference on Reliable software / April 1975.
Niklaus Wirth. PASCAL-S: A Subset and its Implementation // ETH Zurich, June 1975.
Niklaus Wirth. The Use of Modula. Design and Implementation of Modula // ETH Zurich, 1977.
Niklaus Wirth. Modula: A Language for Modular Multiprogramming // Software - Practice and Experience, No. 7, 1977.
Niklaus Wirth. Toward a discipline of real-time programming // Communications of the ACM (CACM), Volume 20, Issue 8 / August 1977.
Niklaus Wirth. Modula-2 // ETH Zurich, March 1980.
Niklaus Wirth. The Personal Computer Lilith // ETH Zurich, April 1981.
Niklaus Wirth. Lilith: A personal computer for the software engineer // ICSE '81: Proceedings of the 5th international conference on Software engineering / March 1981.
Niklaus Wirth. Schemes for multiprogramming and their implementation in Modula-2. Revision and amendments to Modula-2 // ETH Zurich, June 1984.
Niklaus Wirth. From programming language design to computer construction // Communications of the ACM (CACM), Volume 28, Issue 2 / February 1985.
Niklaus Wirth. A Fast and Compact Compiler for Modula-2 // ETH Zurich, July 1985.
Niklaus Wirth. Microprocessor architectures: a comparison based on code generation by compiler // Communications of the ACM (CACM), Volume 29, Issue 10 / October 1986.
Niklaus Wirth. Extension of record types // ACM SIGCSE Bulletin (SIGCSE), Volume 19, Issue 2 / June 1987.
Niklaus Wirth. Hardware architectures for programming languages and programming languages for hardware architectures // ASPLOS II: Proceedings of the second international conference on Architectual support for programming languages and operating systems / October 1987.
Niklaus Wirth. Type extensions // ACM Transactions on Programming Languages and Systems (TOPLAS), Volume 10, Issue 2 / April, 1988.
Niklaus Wirth. The Programming Language Oberon // ETH Zurich, October 1990.
Niklaus Wirth. Brief history of Modula-2 and Lilith // Joint Modular Language Conference '1994, University of Ulm, Germany / 1994.
Niklaus Wirth. A Plea for Lean Software // IEEE Computer, Vol. 28 / February 1995.
Hanspeter Mössenböck, Niklaus Wirth. The Programming Language Oberon-2 // ETH Zurich, March 1995.
Niklaus Wirth. Recollections about the development of Pascal / HOPL II: History of programming languages / January 1996.
Niklaus Wirth. Hardware Compilation. The Translation of Programs into Circuits // ETH Zurich, January 1998.
Niklaus Wirth. A Computer System for Model Helicopter Flight Control. Technical Memo Nr. 1: The Hardware Core // ETH Zurich, January 1998.
Niklaus Wirth. A Computer System for Model Helicopter Flight Control. Technical Memo Nr. 2: The Programming Language Oberon SA // ETH Zurich, March 1999.
Niklaus Wirth. An Essay on Programming // ETH Zurich, March 1999.
Niklaus Wirth. Computing science education: the road not taken // ITiCSE '02: Proceedings of the 7th annual conference on Innovation and technology in computer science education / June 2002.
Niklaus Wirth. A Triptychon of Digital Circuits // ETH Zurich, August 2005.
Niklaus Wirth. Good ideas, through the looking glass // IEEE Computer, Volume 39, Issue 1 / 2006.
Niklaus Wirth. Modula-2 and Oberon // HOPL III: Proceedings of the third ACM SIGPLAN conference on History of programming languages / June 2007.
Niklaus Wirth. Porting the Oberon Compiler from Oberon to Oberon-07 // ETH Zurich, August 2007.
Niklaus Wirth. SET: A neglected data type, and its compilation for the ARM // ETH Zurich, August 2007.
Niklaus Wirth. The Language PICL and its Implementation // ETH Zurich, September 2007.
Niklaus Wirth. PICL: A Programming Language for the Microcontroller PIC // ETH Zurich, October 2007.
Niklaus Wirth. Interrupts and Traps in Oberon-ARM // ETH Zurich, February, 2008.
Niklaus Wirth. A Brief History of Software Engineering // IEEE Annals of the History of Computing, Volume 30, Issue 3 / 2008.
Niklaus Wirth. On Programming Styles // ETH Zurich, March 2008.
Niklaus Wirth. The Year of Informatics // ETH Zurich, March 2008.
Niklaus Wirth. A Microcontroller System for Experimentation // ETH Zurich, April 2008.
Niklaus Wirth. An Oberon Compiler for the ARM Processor // ETH Zurich, April 2008.
Niklaus Wirth. Finite State Machines, Programmable Logic Devices, and the Crux of Growing Complexity // ETH Zurich, September 2008.
Niklaus Wirth. A Note on Division // ETH Zurich, October 2008.
Niklaus Wirth. The Tiny Register Machine (TRM) // ETH Zurich, 2009.
Niklaus Wirth. Experiments in Computer System Design // ETH Zurich, 2010.
Niklaus Wirth. Differences between Oberon-07 and Oberon // ETH Zurich, 2011.
Niklaus Wirth. The Design of a RISC Architecture and its Implementation with an FPGA // ETH Zurich, 2013.
Niklaus Wirth. An Implementation of Lola-2 or Translating from Lola to Verilog // ETH Zurich, November 2014.
Niklaus WIrth. Lola-2: A Logic Description Language // ETH Zurich, September 2015.
Niklaus Wirth. Three Counters // ETH Zurich, October 2015.
Niklaus Wirth. The Programming Language Oberon-07 (Revised Oberon) // ETH Zurich, 2016.
Niklaus Wirth. 50 years of Pascal // Communications of the ACM (CACM), Volume 64, Issue 3 / March 2021.
Pauline Lüthi, Florian Meyer. Computer pioneer Niklaus Wirth has died // ETH Zurich, 04.01.2024.
Martin Odersky. Some Memories of Niklaus Wirth // Language and Code, 04.01.2024.
Liam Proven. RIP: Software design pioneer and Pascal creator Niklaus Wirth // The Register, 04.01.2024.
Dag Spicer. In Memoriam: Niklaus Wirth (1934-2024) // Computer History Museum, 05.01.2024.
Никлаус Вирт: чем ещё известен создатель языка Pascal // Коммерсантъ, 08.01.2024.
Никлаус Вирт и А. П. Ершов. Архивные материалы. Переписка / Новосибирск: Архив академика А. П. Ершова.
Никлаус Вирт. О некоторых основных понятиях языков программирования // Пер. и факсимиле А. П. Ершова. — Stanford University, 1967.
Никлаус Вирт. От разработки языка программирования к созданию компьютера // «Лекции лауреатов премии Тьюринга за первые двадцать лет: 1966-1985». М.: Мир, 1993.
Никлаус Вирт. Долой «жирные» программы // Открытые системы, No. 6, 1996.
Никлаус Вирт. О культуре разработки программного обеспечения // Открытые системы, No. 1, 1998.
Никлаус Вирт, Ханспетер Мёссенбок. Различия между языками Oberon и Oberon-2 // ИнфоАрт, 1998.
Никлаус Вирт. Преподавание информатики: потерянная дорога // ITiCSE, Дания, 2002.
Никлаус Вирт. Краткая история Modula-2 и Lilith // Мир ПК, No. 8, 2003.
Никлаус Вирт. От Modula-2 к Oberon // Мир ПК, No. 8, 2003.
Никлаус Вирт. Modula-2 и объектно-ориентированное программирование // Мир ПК, No. 9, 2003.
Никлаус Вирт. Проектирование системы с нуля // Мир ПК, No. 1, 2004.
Никлаус Вирт, Тони Хоар, Эдсгер Дейкстра. Фотоматериалы // Мир ПК-диск, No. 2, 2004.
Никлаус Вирт. Хорошие идеи: взгляд из Зазеркалья // Открытые системы, 2006.
В. Е. Котов, А. Г. Марчук «Архитектура макета системы МАРС» // ВЦ СО АН СССР, 1986.
Д. Н. Кузнецов, А. Е. Недоря, А. В. Осипов, Е. В. Тарасов. Процессор «Кронос» в мультипроцессорной системе // ВЦ СО АН СССР, 1986.
М. фон-дер-Флаасс. Знакомьтесь: семейство процессоров КРОНОС // Новосибирск, 1988.
Архитектура «Кронос» и ВНТК «СТАРТ» // Материалы из архива А. П. Ершова, 1986-1990.
Архитектура процессоров семейства «Кронос» // Институт систем информатики им. А. П. Ершова СО АН СССР, 1990.
Руководство по операционной системе Excelsior // Институт систем информатики им. А. П. Ершова, СО АН СССР, 1991.
А. Е. Недоря. Расширяемая переносимая система программирования, основанная на биязыковом подходе // Диссертация на соискание степени кандидата физико-математических наук. — Новосибирск, 1992.
И. Егоров, Р. Богатырев, Д. Петровичев. Ещё один подход к реализации механизма обработки исключений в языке Modula-2 // Structured Programming, 1993.
Мартин Рейзер. Краткий экскурс в систему Oberon // Технология программирования, No. 1, 1995.
Евгений Налимов, Алексей Недоря. Перенацеливаемый оптимизирующий Modula-2/Oberon-2 компилятор // Технология программирования, No. 1, 1995.
Руслан Богатырев. Java и Juice: дуэль технологий ?! // Компьютерра, 1996.
Руслан Богатырев. Язык как основа архитектуры. Проект Lilith // ComputerWeek-Moscow, No. 19, 1998.
Руслан Богатырев. Язык как основа архитектуры. Проект «Кронос» и путь к технологиям XDS // ComputerWeek-Moscow, No. 20, 1998.
Руслан Богатырев. Язык как основа архитектуры. Средства кросс-разработки и технологии XDS // ComputerWeek-Moscow, No. 21, 1998.
Сергей Свердлов. Арифметика синтаксиса // PC Week Russian Edition, No. 42-43, 1998.
Руслан Богатырев. Летопись языков. Паскаль // Мир ПК, No. 4, 2001.
Руслан Богатырев. Никлаус Вирт — патриарх надёжного программирования // Мир ПК, No. 9, 2002.
А. А. Колташев. Modula-2 в российском космосе // Информатика-21, 2002.
А. Ф. Рар. Стандарт языка Модула-2 / Под редакцией А. Е. Недори. — Институт систем информатики им. А. П. Ершова СО РАН, 2002.
Тэйлор Хатт. PLSA '94. Конференция по языкам программирования: путевые заметки американца о поездке в Швейцарию // Мир ПК, No. 9, 2003.
Руслан Богатырев. 1988-2003. Эволюция программирования за последние 15 лет // Мир ПК, No. 10, 2003.
И. В. Поттосин. Российские исследования по языкам программирования и трансляции // Мир ПК, No. 12, 2003.
Алексей Недоря. От Паскаля к Оберону, или мечта о сборочном программировании // Мир ПК, No. 9, 2005.
Руслан Богатырев. Язык Oberon. Краткий путеводитель // Мир ПК, No. 9, 2005.
Руслан Богатырев. Судьба Оберона // Мир ПК, No. 9, 2005.
Руслан Богатырев. Oberon как эсперанто программирования // Мир ПК, No. 9, 2005.
Артем Попов, Николай Самсонов. Эксперт мирового масштаба. Интервью с Никлаусом Виртом // Эксперт-Сибирь, No. 40, 2005.
Илья Ермаков. Oberon-технологии: что это такое? // 2006.
Руслан Богатырев. Две культуры программирования // 2007.
Руслан Богатырев. От Oberon к Bluebottle // 2007.
Илья Ермаков. Некоторые идеи архитектуры Oberon-систем // 2007.
Руслан Богатырев. Никлаус Вирт. Большое турне по России // 2009.
Владимир Филиппов. Никлаус Вирт в Академгородке // Виртуальный компьютерный музей Э. М. Пройдакова, 2009.
Алексей Недоря. Держаться корней. К 80-летию Никлауса Вирта // Хабр, 17.02.2014.
Приложение 5. Диссертации учеников и последователей Никлауса Вирта
Christian Jacobi. Code Generation and the Lilith Architecture / ETH Zurich, 1982.
Leo Bernhard Geissmann. Separate Compilation in Modula-2 and the Structure of the Modula-2 Compiler on the Personal Computer Lilith // ETH Zurich, 1983.
Svend Erik Knudsen. Medos-2: A Modula-2 Oriented Operating System for the Personal Computer Lilith / ETH Zurich, 1983.
Robert Griesemer. A Programming Language for Vector Computers / ETH Zurich, 1993.
Michael Franz. Code-Generation On-the-Fly: A Key to Portable Software / ETH Zurich, 1994.
Regis Bernard Joseph Crelier. Separate Compilation and Module Extension / ETH Zurich, 1994.
Josef Templ. Metaprogramming in Oberon / ETH Zurich, 1994.
Marc Michael Brandis. Optimizing Compilers for Structured Programming Languages / ETH Zurich, 1995.
Ralph Olivier Sommerer. Integration of Online Documents / ETH Zurich, 1996.
Johannes Leon Marais. Design and Implementation of a Component Architecture for Oberon / ETH Zurich, 1996.
Wolfgang Weck. On Document-Centered Mathematical Component Software / ETH Zurich, 1996.
Stefan Hans-Melchior Ludwig. Hades: Fast Hardware Synthesis Tools and a Reconfigurable Coprocessor / ETH Zurich, 1997.
Erich Oswald. A Generic 2D Graphics API with Object Framework and Applications / ETH Zurich, 2000.
Pieter Johannes Muller. The Active Object System Design and Multiprocessor Implementation / ETH Zurich, 2002.
Patrik Reali. Using Oberon's Active Objects for Language Interoperability and Compilation / ETH Zurich, 2003.
Thomas Martin Frey. Bluebottle: A Thread-safe Multimedia and GUI Framework for Active Oberon / ETH Zurich, 2005.
Приложение 6. Избранные интервью (Video)
—
Руслан Богатырев — директор Европейского центра программирования им. Леонарда Эйлера, главный редактор арт-журнала «Пантеон».