Программное обеспечение ПЭВМ

4.4. Инструментальные системы

Инструментальной системой будем называть совокупность программного продукта, обеспечивающего разработку информационно-программного обеспечения, и формальных языков, поддерживаемых этим продуктом.

В данном подразделе мы сделаем обзор основных типов инструментальных систем, используемых на ПЭВМ.

4.4.1. Системы программирования

Под системой программирования понимают совокупность языка программирования и виртуальной машины, обеспечивающей выполнение на реальной машине программ, составленных на этом языке.

Языком программирования называют систему обозначений, служащую в целях точного описания алгоритмов для ЭВМ или по крайней мере достаточную для автоматического нахождения такого алгоритма. Эти языки являются искусственными языками со строго определенным синтаксисом и семантикой, поэтому они не допускают свободного толкования конструкций, характерного для естественного языка (языка общения между людьми).

Виртуальная машина – это программный комплекс, эмулирующий работу реальной машины с определённым входным языком на ЭВМ с другим, машинным языком, а иными словами, реализующий входной язык программирования. Такая техника реализации языка программирования позволяет сделать последний удобным для использования человеком. Виртуальная машина содержит транслятор и/или интерпретатор и может включать библиотеки стандартных подпрограмм, отладчик, компоновщик и другие сервисные средства.

Транслятор представляет собой программу, осуществляющую перевод текстов с одного языка на другой. В системе программирования транслятор переводит программу с входного языка этой системы на машинный язык реальной ЭВМ (на которой функционирует данная система программирования или будет функционировать разрабатываемая программа) либо на промежуточный язык программирования, уже реализованный или подлежащий реализации. Одной из разновидностей транслятора является компилятор, обеспечивающий перевод программ с языка высокого уровня (приближенного к человеку) на язык более низкого уровня (близкий к ЭВМ), или машинозависимый язык. Другая разновидность транслятора — ассемблер, осуществляющий перевод программ с языка низкого уровня (языка Ассемблера) на машинный язык, имеющий примерно тот же уровень. Некоторые трансляторы служат для переноса программ с одной машины на другую. Программа, подающаяся на вход транслятора, называется исходной, а результат трансляции — объектной программой. Использование трансляторов обеспечивает высокую скорость выполнения полученных с их помощью программ, однако затрудняет и удлиняет процесс отладки программных продуктов. Последнее обстоятельство объясняется относительно большим временем трансляции и сложностью создания отладчиков, которые должны отображать машинную программу в программу на исходном языке.

Диаметрально противоположными характеристиками обладает альтернативное средство реализации языка — интерпретатор. Интерпретатор представляет собой программный продукт, выполняющий предъявленную программу путем одновременного ее анализа и реализации предписанных ею действий. При использовании интерпретатора отсутствует разделение на две стадии (перевод и выполнение) и, более того, отсутствует явный перевод программы даже по частям перед очередным этапом выполнения. В действительности же распознается очередная конструкция программы и интерпретатором выполняются определяемые ею действия. После этого процессы анализа и реализации предписанных действий циклически повторяются. Таким образом, при интерпретации реально выполняется только программа-интерпретатор, управляемая исходной программой и, естественно, исходными данными для последней.

Возможны и смешанные стратегии реализации языков программирования, например, трансляция на промежуточный язык с последующей интерпретацией промежуточной программы.

Вырожденной является система программирования, поддерживающая машинный язык. В этом случае в качестве основного средства его реализации выступает сама ЭВМ, которую в отличие от программного интерпретатора можно рассматривать как аппаратный интерпретатор.

Главным классифицирующим признаком языков и, следовательно, систем программирования, является принадлежность к одному из оформившихся к настоящему времени стилей программирования, основные среди которых — процедурное, функциональное, логическое и объектно-ориентированное.

Стилю (парадигме) программирования соответствует своя собственная (уникальная) модель вычислений.

На ПЭВМ реализованы представители всех стилей программирования. И вообще следует заметить, что быстрее всего вновь созданные языки воплощаются в системы программирования именно для ПЭВМ, с обеспечением при этом сервиса высочайшего уровня.

Существуют два подхода к конструированию систем программирования:

1) подход, при котором целью является создание комплекса автономных средств, в совокупности выполняющих роль системы программирования;

2) подход, при котором создается интегрированная среда программирования, поддерживающая развитый пользовательский интерфейс и объединяющая в единое целое все средства разработки и выполнения программ (текстовый редактор, компилятор, компоновщик, отладчик и библиотеки стандартных подпрограмм).

Автономные средства позволяют разрабатывать программы большего размера, так как различные этапы разработки программы разнесены во времени, а поэтому сами автономные средства не обязаны одновременно находиться в ОЗУ. Кроме того, можно интенсивно использовать внешнюю память для хранения промежуточных и окончательного результатов ее обработки. Однако применять такие средства неудобно. Интегрированная же среда предоставляет лучший сервис в работе, но предъявляет и более жесткие требования к памяти (или к размеру разрабатываемой программы, что эквивалентно).

Ведущими разработчиками систем программирования в настоящее время являются американские фирмы Borland International и Microsoft.

Первая из них предлагает системы, Содержащие как автономные средства, так и интегрированные среды. Торговой маркой продуктов этой фирмы стала приставка Turbo (а для последнего изделия — BORLAND) к названию системы программирования, совпадающему с наименованием входного языка, например: Turbo Pascal. Дословно же «Тurbо» означает «быстрый», что соответствует действительности.

Фирма Microsoft раньше предлагала только мощные автономные средства, а сравнительно недавно вступила в конкурентную борьбу с фирмой Borland, выпустив интегрированную среду Quick Pascal 1.0 и ей подобные с другими входными языками. Между прочим, Quick тоже означает «быстрый».

Системы программирования предлагаются и многими другими фирмами-разработчиками ПО. Ниже мы кратко охарактеризуем основные стили программирования и рассмотрим относящиеся к ним системы программирования, доступные на ПЭВМ.

Процедурное программирование

Процедурное (императивное) программирование является отражением архитектуры традиционных ЭВМ, которая была предложена фон Нейманом в 40-х гг. Теоретической моделью процедурного программирования служит алгоритмическая система под названием «машина Тьюринга».

Программа на процедурном языке программирования состоит из последовательности операторов (инструкций), задающих те или иные действия. Основным является оператор присваивания, служащий для изменения содержимого областей памяти. Вообще концепция памяти как хранилища значений, содержимое которого может обновляться операторами программы, является фундаментальной в императивном программировании.

Выполнение программы сводится к последовательному выполнению операторов с целью преобразования исходного состояния памяти (т.е. значений переменных) в заключительное. Таким образом, с точки зрения программиста имеется программа и память, причем первая последовательно обновляет содержимое последней.

Процедурные языки характеризуются:

Из-за наличия побочных эффектов (т.е. взаимного влияния различных программных модулей через общую память) программы на таких языках трудно читаемы, плохо модифицируемы и трудно проверяемы, а следовательно, ненадежны. По этой же причине они предполагают лишь последовательное выполнение.

Символьные вычисления состоят в преобразовании динамических структур данных, т.е. структурированных объектов, конфигурация которых меняется во времени (в отличие от числовых вычислений, предполагающих обработку данных статической структуры). К символьным вычислениям относятся задачи искусственного интеллекта, сортировки, трансляции, интерпретации, управления базами данных, символической алгебры и др. Символьные вычисления имеют ряд особенностей:

Одним из важнейших классификационных признаков процедурных языков является их уровень. Уровень языка программирования определяется семантической (смысловой) емкостью его конструкций и его ориентацией на программиста-человека Язык программирования (частично) ликвидирует семантический разрыв между методами решения задач человеком и машиной. Чем более язык ориентирован на программиста, тем выше его уровень. Распределение основных реализованных на ПЭВМ императивных языков по уровням приведено на рис. 4.4. Ряд языков программирования на нем не представлен. Среди них FORTH, который трудно классифицировать по уровню, а также PL/1, Cobol, RPG, Logo, Snobol и GPSS, в настоящее время не пользующиеся большой популярностью.

Рис. 4.4. Уровни процедурных языков программирования

Двоичный язык является не чем иным, как непосредственно машинным языком. В настоящее время такие языки программистами не применяются.

Шестнадцатеричный язык обеспечивает некоторое упрощение записи программы на машинном языке путем представления четырех двоичных цифр одной шестнадцатеричной. Этот язык используется в качестве дополнения к языкам высокого уровня, таким, как Pascal, для программирования критичных к времени выполнения фрагментов алгоритмов.

Язык Ассемблера — это язык, предназначенный для представления в удобочитаемой символической форме программ, записанных на машинном языке. Он позволяет программисту пользоваться мнемоническими кодами операций, по своему усмотрению присваивать символические имена регистрам ЭВМ и ячейкам памяти, а также задавать наиболее удобные в том или ином контексте схемы адресации. Кроме того, язык Ассемблера обеспечивает представление констант в различных системах счисления (например, в десятичной или шестнадцатеричной).

Язык детализированных схем программ — это не язык программирования, а язык представления алгоритмов при разработке программ, некогда широко используемый. В связи с достаточно низким уровнем этот язык в настоящее время на практике почти не применяется, а предпочтение отдается более развитым языкам проектирования программных комплексов. Мы показали язык детализированных схем программ на рисунке лишь затем, чтобы стало понятным его место в иерархии процедурных языков программирования.

Язык Макроассемблера является расширением языка Ассемблера за счет включения макросредств. С их помощью предоставляется возможность описывать в программе последовательности инструкций с параметрами (макроопределения) и использовать снабженные аргументами макрокоманды, которые автоматически замещаются в процессе ассемблирования макрорасширениями, представляющими собой макроопределения с подставленными вместо параметров аргументами. Иными словами, язык Макроассемблера предоставляет средства определения и использования новых, более мощных команд как последовательностей базовых инструкций, что несколько повышает его уровень.

Языки Ассемблера и Макроассемблера применяются системными программистами-профессионалами с целью использования всех возможностей оборудования ЭВМ и получения эффективной, как по времени выполнения, так и по потребному объему памяти, программы.

Язык программирования С первоначально разработан для реализации ОС UNIX в начале 70-х гг. ее создателями и в последующем приобрел высокую популярность среди системных, а также (частично) среди прикладных программистов. В настоящее время этот язык реализован в рамках большинства ОС ЭВМ и особенно ПЭВМ. В С сочетаются достоинства современных высокоуровневых языков (в части управляющих структур, а также структур данных) и возможность доступа к аппаратным средствам машины на уровне, который обычно ассоциируется с языком Ассемблера. С имеет синтаксис, обеспечивающий чрезвычайную краткость программ, а компиляторы вследствие особенностей языка способны генерировать весьма эффективный объектный код. Этот язык разработан на базе языка BCPL; промежуточной версией, которая просуществовала недолго, был язык В. В языке С воплощены основные концепции языка Pascal (но не только они). Одна из наиболее существенных особенностей языка С состоит в нивелировании различий между выражениями и операторами, что приближает его к функциональным языкам. В частности, выражение может обладать побочным эффектом (эффектом присваивания), а также может использоваться в качестве оператора. Нет также четкой границы между процедурами и функциями. Более того, понятие процедуры вообще не вводится. Вместе с тем синтаксис языка таков, что затрудняет программирование и понимание составленных программ. Отсутствует также строгая типизация, что не способствует получению надежных программ.

Basic (Beginner's All-purpose Symbolic Instruction Code — многоцелевой язык символических инструкций для начинающих) представляет собой простой язык программирования, разработанный в 1964 г. для использования новичками. История Basic'a такова. Еще в 1962 г. профессор математики Дортмутского колледжа Т.Куртц предложил директору, чтобы студенты изучали вычислительную технику в течение всех четырех лет обучения. Но ЭВМ тех лет не позволяли реализовать эту идею, так как компиляция программ осуществлялась непомерно долго, а пользователи при этом не присутствовали. Для получения (как правило) ошибочного листинга требовалось несколько дней. Поэтому было решено разработать простейший язык для непосредственного общения человека с машиной. Вот почему работа в среде Basic'a первоначально велась только в режиме интерактивной (диалоговой) интерпретации. В настоящее время имеются и компиляторы с этого языка. На ранних этапах своего развития Basic применялся только для обработки числовых величин; позднее он был расширен средствами обработки строк. Basic по концепциям, заложенным при его разработке, в смысле строгости и стройности является антиподом языка Pascal. В частности, в нем широко используются разного рода умолчания, что считается плохим тоном в большинстве современных языков. Несмотря на это, Basic очень популярен, в особенности на ПЭВМ. Существует множество его диалектов, несовместимых между собой. Не без оснований этот язык иногда сравнивают с питоном, заглатывающим и переваривающим все новое, что появляется в других языках программирования. Поэтому Basic является одним из наиболее динамичных, а его уровень нельзя определить однозначно. Современные диалекты Basic'a весьма развиты и мало чем напоминают своего предка.

Язык Fortran был разработан в 1956 г. сотрудником фирмы IBM Дж.Бэкусом. В 1958 г. появилась версия Fortran-II, которую затем сменил язык Fortran-IV, стандартизованный в 1966 г. Американским национальным институтом стандартов (ANSI) и поэтому называемый также Fortran 66. Он стал поистине «рабочей лошадью» научных работников и широко используется в настоящее время, несмотря на его ограниченность и «корявость». Со временем появилась следующая версия языка Fortran-77, а в 1988 г. — новые версии — Fortran 8х, содержащая ряд черт функциональных языков программирования, и Fortran 88. Отметим, что в версии Fortran-II впервые была реализована идея раздельной компиляции модулей, что дало возможность создавать, в частности, библиотеки научных подпрограмм. И наконец, подчеркнем, что вследствие своей простоты язык Fortran позволяет сгенерировать достаточно эффективный машинный код.

Одним из наиболее популярных, среди прикладных программистов, процедурных языков программирования вообще и тем более для ПЭВМ является язык Pascal. Он разработан в 1970 г. швейцарским специалистом в области вычислительной техники профессором Н.Виртом, назван в честь французского математика и по замыслу автора предназначался для обучения программированию. Однако язык получился настолько удачным, что стал одним из основных инструментов прикладных, а зачастую и системных программистов при решении задач как вычислительного, так и информационно-логического характера. Эволюция Pascal'я привела к появлению множества несовместимых его диалектов, в той или иной мере дополняющих концепции Вирта, что потребовало стандартизации языка В настоящее время существуют три Pascal-стандарта: британский стандарт BS6192:1982 г., международный стандарт ISO 7185:1983 г., идентичный предыдущему, и ANSI-стандарт. В Pascal'e реализован ряд концепций, в настоящее время рассматриваемых как основа для «дисциплинированного» программировании и заимствованных разработчиками многих других языков. Одним из наиболее существенных новшеств в Pascal'e является последовательная и в определенном смысле полная реализация концепций структурного программирования не только путем упорядочения связей между фрагментами программы по управлению, но и за счет структуризации данных. Так, в Pascal'e, по всей видимости, впервые воплощена концепция определения новых типов данных. Этот язык в отличие от С является строго типизированным. Pascal характеризуется:

Следующим созданным Н.Виртом в 1979 г. языком был язык Modula-2, первоначально предназначенный для ПЭВМ Lilith. Modula-2 — это, по существу, развитие Pascal'я. Его особенности состоят в высокой модульности программ, наличии средств описания параллельных процессов, а также механизмов синхронизации. Модули предполагают наличие секции интерфейса и реализации, а также поддерживают механизм экспорта/импорта, что в совокупности и обеспечивает высокую степень независимости модулей. Подобно С в нем присутствуют низкоуровневые средства. Поддерживаются также развитые средства абстракции данных.

В настоящее время Modula-2 реализован на большинстве ПЭВМ и для различных ОС. Наиболее полно возможности языка могут проявиться только при использовании многозадачной ОС (например, OS/2 или UNIX) на ПЭВМ, допускающей многопрограммную работу.

В 1988 г. Н.Вирт предложил новый язык под названием Oberon, который уже реализован на АРМ с МП NS32032 в виде интегрированной среды программирования. Он является прямым потомком языка Modula, но проще и мощнее последнего, однако не имеет средств асинхронного программирования. Дополнительная его особенность состоит во введении концепции расширяемых типов.

Язык Ada разработан в 1979 г. ведущими специалистами в области программирования по заказу Министерства обороны США для использования во встроенных системах с управляющими ЭВМ, что требует поддержки режима реального времени. ANSI-стандарт этого языка принят в 1983 г., а с 1986 г. он стал обязательным для многих военных приложений. Язык назван в честь Августы Ады Лайвлейс, которая была ассистентом Ч.Бэббиджа и по праву считается первым в мире программистом. Несмотря на то, что основное назначение языка Ada — написание больших программных систем реального времени, не исключается, конечно, его использование и при решении задач вычислительного характера, системного программирования, параллельной обработки и т.п. Поэтому он вполне может рассматриваться как универсальный язык программирования. Язык Ada — это современный язык программирования, содержащий такие возможности паскалеподобных языков, как определение типов, развитые управляющие структуры и подпрограммы. Более того, в нем собраны многие теоретические достижения, полученные после 1970 г. Язык поддерживает логическую модульность, для которой данные, типы и подпрограммы могут быть пакетами. Физическая же модульность достигается раздельной компиляцией. Программирование в реальном масштабе времени обеспечивается за счет механизма распараллеливания и обработки исключений. Системное программирование поддерживается путем организации доступа к системно-зависимым параметрам и управления точностью при представлении данных. Следует отметить также, что данный язык вводит достаточно строгую дисциплину програм­мирования, чем препятствует написанию «плохих» программ. Несмотря на достоинства, программистов отталкивает его громоздкость, и этот язык прокладывает себе дорогу с большим трудом. Некоторые же средства языка принципиально неэффективны в смысле потребностей в ресурсах при их реализации. В сравнении с языком Modula-2 язык Ada имеет несколько более богатые выразительные возможности, но существенно сложнее его.

Язык программирования APL (A Programming Language) был создан Иверсоном в 1969 г. и сразу получил широкое распространение. К числу его основных преимуществ относятся богатый набор мощных операторов, позволяющих работать с многомерными массивами как с единым целым, а также предоставление пользователю возможности определять собственные операторы. Для записи встроенных операторов используются в основном одиночные символы из набора специальных знаков. Поэтому программы на языке APL очень компактны и вместе с тем зачастую малопонятны. Основное его назначение — обработка массивов.

Многими разработчиками ПО для ПЭВМ используется гибкий и достаточно простой язык FORTH (четвертый), разработанный Ч.Муром в 1971 г. Программа на этом языке имеет вид строк в обратной польской записи (сначала записываются операнды, а затем — операция). Основной структурой данных при организации вычислений является стек (магазин). Важная особенность FORTH'a — его открытость (расширяемость). Программист может легко добавлять новые операции, типы данных и операторы. Последнее достигается путем связывания любой строки программы с заданным программистом словом, которое затем может использоваться наравне со стандартными операторами. Однако расширение словаря ведет к снижению эффек­тивности программы. FORTH позволяет программисту получать полный доступ ко всем средствам ЭВМ. В этом смысле он сочетает в себе (как и С) достоинства языков высокого и низкого уровней. Язык FORTH используется для решения, в основном, задач информационно-логического, а не вычислительного характера, и хорошо зарекомендовал себя при работе в режиме реального времени. Сама система FORTH очень компактна.

Некогда популярный на больших ЭВМ мощный, но неоднородный конгломерат языков Fortran, Algol и Cobol под названием PL/1 в настоящее время, видимо, безвозвратно сдал свои позиции и на ПЭВМ практически не используется, хотя и имеется ряд ограниченных его реализаций. Этот язык достаточно сложен и имеет такие свойства, которые не стимулируют написание корректных, надежных и наглядных программ. Кроме того, его реализация ресурсоемка и поэтому неэффективна

Ориентированным на обработку коммерческой информации является язык Cobol, разработан­ный в 1960 г. и за период своего существования, как многие языки, претерпевший ряд изменений. В настоящее время используются стандарты Cobol-74, Cobol-68 и Cobol-85.

Применяется также язык SNOBOL, предназначенный, главным образом, для обработки тек­стовых данных. Он включает в себя мощные операторы для сравнения фрагментов текста и поиска заданных цепочек символов. Существующей на сегодняшний день версией SNOBOL IV предусматриваются средства для работы и с другими типами данных, фактически это в достаточной степени универсальный язык с ярко выраженными средствами обработки текстов.

С целью обучения детей в 1967 г. разработан и используется по настоящее время язык LOGO. Он отличается простотой, но весьма богатыми возможностями, среди которых процедуры, графи­ческие средства и др.

Специально для генерации отчетов служит язык программирования RPG (Report Program Generator). Вход в систему RPG состоит из описания структуры файла, спецификации нужной информации и расположения ее на странице. На основе этой информации система RPG строит программу для считывания файла, извлечения из него нужной информации и переформатирования ее требуемым образом.

Интересные возможности предоставляет система GPSS, ориентированная на моделирование систем массового обслуживания.

Представляет значительный интерес и параллельный язык OCCAM, используемый для про­граммирования транспьютеров английской фирмы Inmos, которые, как уже отмечалось, могут выполнять роль акселераторов для ПЭВМ.

По не вполне ясным причинам языки семейства Algol на ПЭВМ не представлены. Algol-60 был разработан коллективом известных в то время в области программирования специалистов и составил непосредственную конкуренцию Fortran'у. Он отличался от Fortran'a в лучшую сторону, однако марка фирмы IBM сделала в данном случае свое «черное» дело и последний стал доминирующим. Версия Algol-68 обладала богатым набором средств, высокой строгостью и стройностью, но и большой сложностью. Ее реализация затянулась на долгие годы, в результате чего время было упущено и данный язык в некотором смысле пережил самого себя (проще сказать — устарел), практически прекратив свое существование.

Сведения о системах процедурного программирования для ПЭВМ в алфавитном порядке названий языков приведены в табл. 4.4. В графе «Способ реализации языка» использованы сокращения К, А и И для компиляции, ассемблирования и интерпретации соответственно. В графе же «Тип системы программирования» буквы А и И соответственно обозначают автономные средства и интегрированную среду программирования. Сведения о системах программирования для UNIX-подобных систем неполны.

Подавляющее большинство систем процедурного программирования основано на трансляции, что является естественным следствием отражения ими архитектуры современных ЭВМ, в том числе ПЭВМ. Это обстоятельство как раз и обеспечивает возможность перевода программ на машинный язык.

Расставим некоторые акценты и сделаем ряд замечаний, не нашедших отражения в приведенной таблице.

Система Artek Ada включает практически весь стандарт языка. Остальные же Ada-системы ограничиваются лишь его подмножеством.

Продукт APL PLUS (STSC) совершеннее системы APL (IBM).

Для реализации языка Ассемблера используются утилиты DEBUG и LINK, включенные в состав DOS. Первая из них позволяет ассемблировать исходные программы с получением объектного модуля и отлаживать исполняемые (загрузочные) модули, а вторая — компоновать объектные модули в единый загрузочный модуль.

Системы BASIC, BASICA, GW-BASIC и QBASIC также являются составными частями DOS и называются утилитами, хотя это и несправедливо. Достоинства продукта BASICA — предо­ставляемые программисту графические возможности и средства работы с дисками. А в принципе системы BASICA и GW-BASIC аналогичны, но разработаны различными фирмами. QBASIC входит в состав MS-DOS 5.0 и представляет собой заметный шаг вперед в сравнении с GW-BASIC. Система True BASIC реализует ANSI-стандарт языка 1984 г.

Среди С-систем наиболее мощной является BORLAND С++. Эта система, являясь развитием системы Turbo С(++), поддерживает языки С и С++ и предназначена для разработки программ, работающих в среде DOS или Windows. Сам же язык С++ — это усовершенствованный язык С, в который включены объектно-ориентированные средства. В С++ имеются также другие особенности. Вообще фирма Borland International прекратила работы по всем языкам программирования, за исключением С(++), Pascal и языка Макроассемблера. Зато оставшиеся системы — лучшие в своем классе.

Богатыми возможностями обладает также Microsoft С Compiler 6.0.

Многие системы, такие, как Turbo С и WATCOM С, имеют хорошую совместимость с ANSI-стандартом языка 1989 г. Дополнительной особенностью продукта WATCOM С 6.5 является то, что он генерирует машинные коды с наилучшими показателями по скорости их работы. Компилятор РСС отличается от СС для UNIX своей мобильностью. Особенности назначения компиляторов для ОС AIX состоят в следующем:

СС — основной компилятор;

FCC — для использования сопроцессора плавающей точки;

VCC — для получения объектных файлов в формате VRM;

SCC — для получения автономных программ.

Среди Макроассемблеров снова лучшим является изделие фирмы Borland International Turbo Assembler. Он поддерживает работу как в режиме MASM, обеспечивая совместимость с системой Macro Assembler фирмы Microsoft, так и в режиме IDEAL, т.е. в собственном улучшенном режиме.

Отличается хорошими характеристиками система TopSpeed Modula-2 для DOS и OS/2, как и другие изделия фирмы Jensen & Partners International. Она содержит высокоскоростной опти­мизирующий компилятор, интерфейс с пользователем типа «меню», многооконный многофай­ловый текстовый редактор и быстрый «интеллектуальный» компоновщик.

Недавно фирма Jensen & Partners International предложила систему TopSpeed 3.0, имеющую мо­дульную структуру и позволяющую работать на четырех языках (Modula-2, Pascal, С и С++), просто меняя компиляторы. В основе системы лежат модули TopSpeed Environment (среда программи­рования для DOS и OS/2) и TopSpeed TechKit. С помощью последнего можно создавать программы для Windows и РМ.

Среди Pascal-систем лидером является Turbo Pascal 6.0. А конкурирует с ней Quick Pascal 1.0. Интегрированный вариант Turbo Pascal 6.0 содержит:

— многооконный текстовый редактор для подготовки программ и данных;

— быстрый компилятор;

— «интеллектуальный» компоновщик, обеспечивающий удаление из программы при форми­ровании загрузочного модуля неиспользуемых подпрограмм, что важно для воплощения концепции модулей (см. ниже);

— превосходный интерактивный отладчик, позволяющий выполнять программу по частям и после каждого этапа выполнения просматривать, а также изменять значения переменных, причем точки останова могут быть условными;

— развитый контекстно-зависимый интерактивный справочник;

— богатые библиотеки стандартных подпрограмм (стандартные модули).

Таблица 4.4

Системы процедурного программирования для ПЭВМ

Язык

 

Наименование системы программирования

Фирма-разработчик

Способ реализации языка

Требуемая ОС

Тип системы программирования

Ada

ALSYS PC-AT ADA

Alsys

K

DOS

н/д

 

Artek Ada

Artek

K

DOS

н/д

 

Janus

RR Software

X

CP/М

н/д

 

Janus/ADA

RR Software

X

DOS

н/д

 

Supersoft Ada

Supersoft

К

CP/M

н/д

APL

APL

IBM

К

DOS

н/д

 

APL PLUS

STSC

К

DOS

н/д

Язык Аc-

Assembler

Microsoft, IBM

A

DOS

A

ceмблера

 

 

 

 

 

Basic

Turbo Basic 1.1

Borland International

K

DOS

M

 

Thoroughbred BASIC

Concept Omega

И

DOS

M

 

Pro-Basic

DEC

н/д

н/д

н/д

 

CBASIC-86

Digital Research

M

CP/H

н/д

 

CBASIC-86 Compiler

Digital Research

К

CP/M

н/д

 

Utah BASIC

Ellis Computing

M

DOS

н/д

 

PopBASIC 3.0

Hedge Systems

И&K

DOS

И

 

BASICA

IBM

M

DOS

A

 

BASIC-80

Microsoft

И

CP/M

н/д

 

BASIC Compiler 6.0

Microsoft

К

DOS, OS/2

А

 

GW-BASIC

Microsoft

И

DOS

A

 

QBASIC

Microsoft

И

DOS

A

 

Quick BASIC 4.5

Microsoft

И-К

DOS

И

 

BASIC

Microsoft, IBM

И

DOS

A

 

387BASIC

Microway

К

DOS

н/д

 

BASIC Professional

Morgan

н/д

н/д

н/д

 

Better BASIC

Summit Software Technology

К

DOS

н/д

 

True BASIC 2.1

True Basic

К

DOS,
Apple DOS, Macintosh OS, Amiga

И

 

Watcom BASIC

Watcom Products

И&K

DOS

н/д

 

ZBASIC

Zedcor

X

DOS, CP/M

н/д

C

Turbo C 2.0

Borland International

X

DOS

A&H

 

Turbo C++ 2.8

Borland International

K

DOS

A&И

 

BORLAND C++ 3.0

Borland International

К

DOS C+Uindows)

A&И

 

C 86 PLUS 1.28d

Computer Innovations

X

DOS

A

 

DeSmet DC88 3.1

C-Ware

K

DOS

A

 

DR C

Digital Research

K

CP/M

н/д

 

Eco-C88 4.15

Ecosoft

X

DOS

A

 

CC

IBM

X

AIX

н/д

 

FCC

IBM

X

AIX

н/д

 

VCC

IBM

K

AIX

н/д

 

SCC

IBM

K

AIX

н/д

 

TopSpeed C

Jensen&Partners International

K

DOS

И

 

TopSpeed C OS/2

Jensen&Partners Internat iona1

K

OS/2

И

 

TopSpeed C++

Jensen&Partners Internationa1

K

DOS

И

 

TopSpeed C++ OS/2

Jensen&Partners Internat iona1

 

OS/2

И

 

Lattice C 6.8

Lattice

К

DOS, OS/2

A

 

Power C 1.2

MIX Software

К

DOS, CP/M

A

 

Aztec C86 4.1c

Мanx Software Systems

К

DOS, CP/M,

A

 

 

 

 

Apple DOS,

 

 

 

 

 

Macintosh OS

 

 

Let's C

Hark Williams Company

К

DOS

н/д

 

High C 1.61

МetaWare

К

DOS, ОS/2

A

 

C Compiler 6.0a

Microsoft

К

DOS, 05/2

A

 

Quick C 2.0

Microsoft

К

DOS

И

 

Quick C Compiler 2.0 with Quick

Microsoft

К

DOS

И

 

Assembler

 

 

 

 

 

C

The Santa Cruz Operation

К

Xenix

 

 

 

 

 

System V

 

 

WATCOM C 8.0

WATCOM Product

К

DOS

A&И

 

Zortech C 1.06

Zortech

K

DOS

A

 

Zortech C++ 2.18

Zortech

K

DOS

A&И

 

CC

н/д

К

UNIX 2.9BSD,

н/д

 

 

 

 

UNIX 4.2BSD,

 

 

 

 

 

ДЕМ0С-2,

 

 

 

 

 

ДЕМОС-32

 

 

PCC

н/д

К

то же  

н

Cobol

Level II Cobol

Digital Research

К

CP/M

н/д

 

Utah COBOL 5.0

Ellis Computing

К

DOS

н/д

 

Cobol Compiler           

IBM

К

DOS

н/д

 

Cobol/2

МicroFocus

К

DOS, 0S/2+PМ

н/д

 

Cobol 3.8

Microsoft          

К

DOS, Xenix,

н

 

 

 

 

OS/2

 

 

 

Cobol 86

Microsoft

К

CP/М

н/д

FORTH

80x8x Forth 2.21

H.Laxen&H.Perry

K

DOS

И

 

PC/Forth

Laboratory Microsystem

К

DOS

н

 

Neon

Kriya Systems

K

Apple DOS,

н

 

 

 

 

 

Macintosh OS

 

 

Forth

MP I

К

CP/M

н

 

Forth

Supersoft

K

CP/M, DOS

н

Fortran

AC/FORTRAN-77

Absoft

К

Macintosh OS

н

 

FORTRAN-77

DEC

К

н

н

 

Utah FORTRAN

Ellis Computing

К

DOS

н

 

Lahey FORTRAN F77L

Lahey Computer Systems

К

DOS

н

 

FORTRAN Compiler 5.0

Microsoft

К

DOS, OS/2

А

 

FORTRAH-77

Microsoft

К

DOS

н

 

FORTRAN-77

PECAN

К

DOS, Amiga

н

 

Pro-FORTRAN

Prospero

К

DOS

н

 

FORTRAN-66

Supersoft

К

CP/M

н

GPSS

GFSS/PC

Minuteman Software

и

DOS

н

LOGO

Logo

Apple Computer

и

Apple DOS

н

 

Object LOGO

Coral Software

и

Apple DOS

н

 

DR Logo

Digital Research

н/д

CP/M

н

 

Logo

IBM

н/д

DOS

н

Язык

Object Assembler

Apple Computer

А

Apple DOS

н

Макроас-

AVMAC

Avocet Systems

А

DOS

н

ceмблера

Turbo Assembler 2.5

Borland International

А

DOS

А

 

Мacro Assembler 5.1

Мicrosoft

А

DOS, OS/2

А

Мodula-2

TopSpeed Мodula-2

Jensen&Partners International

К

DOS

И

 

TopSpeed Мodula-2 OS/2 1.28

Jensen&Partners International

К

OS/2

и

 

Modula-2/86

Logitech

К

DOS, Xenix

н

 

Modula-2 OS/2 1.00

Logitech

К

OS/2

н

 

Nodula-2

PECAN

К

DOS,Amiga,

н

 

 

 

 

Macintosh OS

 

 

Modula-2

Volition

К

DOS

н

 

Professional Modula-2

Stony Brooks Software

К

OS/2

н/д

Pascal

Object Pascal

Apple Computer

К

Apple DOS

н/д

 

Turbo Pascal 6.0

Borland International

К

DOS

А&И

 

Turbo Pascal for Windows

Borland International

К

DOS+Windows

А&И

 

Pascal/МT+86

Digital Research

К

СР/М

н/д

 

Utah PASCAL

Ellis Computing

К

DOS

н/д

 

Pascal

IBM

К

DOS

н/д

 

TopSpeed Pascal

Jensen&Partners International

К

DOS

И

 

TopSpeed Pascal OS/2

Jensen&Partners International

К

OS/2

И

 

Pascal Compi1er 4.0

Microsoft

K

DOS, OS/2

А

 

Quick Pascal 1.8

Microsoft

К

DOS

И

 

UCSD PASCAL

PECAN

К

DOS,Amiga,

н/д

 

 

 

 

Macintosh OS

 

 

Pro-Pascal

Prospero

К

DOS

н/д

PL/1

PL/1-88

Digital Research

К

CP/М

н/д

 

PL/N

Intel

К

ISIS-11

н/д

 

PL/М-86

Intel

К

DOS

н/д

 

PL/Z

Zilog

К

CP/М

н/д

RPG

RPG II Compi1er

Lattice

К

DOS

н/д

SNOBOL

SNOBOL 4

Betstis International

К

DOS

н/д

Все это объединено единым удобным многооконным интерфейсом типа «меню». Сам же язык Turbo Pascal 6.0, базируясь на ANSI-стандарте, развивает его следующим образом: — поддерживает средства объектно-ориентированного программирования;

— имеет дополнительные стандартные типы;

— реализует аппарат типизированных констант,

— поддерживает новые операции;

— имеет средства приведения типов;

— включает ряд усовершенствованных операторов управления;

— имеет усовершенствованный механизм передачи аргументов подпрограммам;

— имеет непосредственный доступ к средствам ОС, портам ввода-вывода, ОЗУ и видеопамяти;

— предоставляет возможность включения в программу машинных кодов и инструкций языка Ассемблера, а также комплексирования программ с ассемблерными модулями;

— имеет дополнительные средства управления динамической памятью, что позволяет, в ча­стности, создавать и обрабатывать динамические массивы;

— допускает разработку многомодульных и оверлейных программ с раздельной компиляцией модулей (оверлейная программа загружается в ОЗУ по частям, что снимает проблему ограни­ченности его объема);

— трактует модуль как библиотеку описаний, а не просто как подпрограмму, что перекликается с концепцией модуля в языке Modula-2, обеспечивая высокую степень независимости фрагментов программы;

— благодаря наличию семейства стандартных программных модулей допускает использование дополнительных предопределенных констант, типов, переменных и подпрограмм;

— имеет объектно-ориентированную среду разработки прикладных программ, обеспечивающую создание оконных пользовательских интерфейсов;

— имеет мощную графическую подсистему, позволяющую формировать и выводить на экран дисплея изображения;

— имеет средства условной компиляции, позволяющие автоматически формировать текст программы;

— предоставляет возможность управлять генерацией объектного кода с помощью директив. В сравнении с охарактеризованной системой среда Quick Pascal обладает следующими осо­бенностями:

— не имеет средств создания оверлейных программ;

— не поддерживает возможность размещения загрузочного модуля в ОЗУ (а не в файле на диске), что не позволяет сократить время выполнения вновь разработанной или откорректиро­ванной программы;

— объектно-ориентированные расширения языка не обеспечивают раннее (на этапе компиляции) «связывание» объектов со своими методами, что также снижает время выполнения программ (Turbo Pascal же обеспечивает как раннее, так и позднее, в ходе выполнения программы, «связывание»).

Подчеркнем, что обе охарактеризованные системы поддерживают язык Pascal, дополненный объектно-ориентированными средствами, и поэтому в равной степени могут быть отнесены к системам объектно-ориентированного программирования. Мы их рассмотрели здесь лишь потому, что интегрированные среды Pascal'я без таких расширений фирмами Borland и Microsoft в настоящее время не предлагаются.

Отметим, что система TopSpeed Pascal также поддерживает объектно-ориентированные средства

Что касается языка PL/1, то все представленные системы реализуют лишь ограниченные подмножества языка.

Несмотря на наличие отладчиков в системах программирования, фирмы Borland и Microsoft предлагают также автономные отладчики Turbo Debugger 2.5 и Codeview 2.2 соответственно, обладающие дополнительными возможностями. Первый отладчик во всех отношениях лучше второго. Turbo Debugger 2.5 позволяет осуществлять интерактивную отладку программ на языках Pascal, С( ++) и Ассемблера как в терминах исходных языков, так и в терминах машинных кодов. Данным отладчиком обеспечивается даже обратное выполнение программ (откат назад). Имеется великолепный пользовательский интерфейс.

Фирма Borland International дополнительно предлагает новый продукт — Turbo Profiler, позволяющий оценить эффективность программы и отдельных ее фрагментов.

Функциональное программирование

Кратко и точно сущность функционального (аппликативного) программирования определена А.П.Ершовым как «... способ составления программ, в которых единственным действием является вызов функции, единственным способом расчленения программы на части является введение имени для функции, а единственным правилом композиции — оператор суперпозиции функции. Никаких ячеек памяти, ни операторов присваивания, ни циклов, ни, тем более, блок-схем, ни передачи управления».

Аппликативное программирование базируется на одной из первых алгоритмических систем — l-исчислении À.×åð÷à, а также родственном ему исчислении комбинаторов, предложенном советским математиком М.И.Шейнфинкелем еще в 1924 г. и развитом Х.Карри. Именно исчисление комбинаторов является исторически первой алгоритмической системой, хотя многие об этом забывают.

Роль основной конструкции в функциональных языках играет выражение. К выражениям относятся скалярные константы, структурированные объекты, функции, тела функций и вызовы функций. Функция трактуется как однозначное отображение из Хn в X, где X — множество выражений, что полностью соответствует понятию функции в математике.

Любой аппликативный язык программирования включает следующие элементы:

1) классы констант, которыми могут манипулировать функции;

2) набор базовых функций, которые программист может использовать без предварительного определения;

3) правила построения новых функций из базовых;

4) правила формирования выражений на основе вызовов функций.

Программа представляет собой совокупность описаний функций (возможно, вложенных) и выражения, которое необходимо вычислить. Оно вычисляется посредством редукции (т.е. серии упрощений) до тех пор, пока это возможно, по следующим правилам:

1) вызовы базовых функций заменяются соответствующими значениями;

2) вызовы небазовых функций заменяются их телами, в которых параметры замещены аргументами. Так как в выражении одновременно могут присутствовать несколько вызовов функций, то

операционная семантика должна определять и стратегию вычисления. В рамках теории уста­новлено, что любая стратегия вычисления ведет к получению одного и того же результата, если вычислительный процесс обрывается. Поэтому вызовы функций можно вычислять од­новременно, что открывает широкие перспективы по автоматическому распараллеливанию программ.

Следовательно, функциональное программирование не использует концепцию памяти как хранилища значений переменных. Операторы присваивания отсутствуют, вследствие чего переменные обозначают не области памяти, а объекты программы, что полностью соответствует понятию переменной в математике. (В действительности можно составлять программы вообще без переменных.) Кроме того, нет существенных различий между функциями и константами, т.е. между программами и данными. В результате этого функция может быть значением вызова другой функции (функции порядка выше первого), и может быть элементом структурированного объекта. Число аргументов в вызове функции не обязательно должно совпадать с числом параметров при ее описании. При недостатке аргументов значением вызова будет функция, а при избытке — либо функция, либо кон­станта, если такой вызов имеет смысл.

Перечисленные свойства характеризуют аппликативные языки как языки программирования сверхвысокого уровня.

Аппликативное программирование можно считать дальнейшим развитием идей структурного программирования за счет структуризации не только управляющих связей и данных, но и инфор­мационных связей. Действительно, процедурным языкам неотъемлемо присуща неупорядоченная связь по данным между различными участками программы. В аппликативной же программе любой программной функции аргументы могут быть переданы только явно, посредством вызова последней, а вычисление значения функции не способно привести к изменению значений каких-либо переменных. Это обеспечивает ясную иерархическую структуру программ (хорошую чита­бельность, проверяемость и совместимость), а следовательно, более высокую надежность. Фун­кциональные языки отличаются своей простотой, легкостью реализации, компактностью пред­ставления алгоритмов, полностью автоматическим распределением памяти и пригодностью для символьных вычислений. Последнее объясняется тем, что по соображениям общности и эффек­тивности реализации основными структурированными объектами в аппликативных языках яв­ляются списки (упорядоченные последовательности объектов, в том числе списков), удобные для символьной обработки; кроме того, в аппликативном программировании легко организуется рекурсивная обработка структурированных объектов. Числовые же вычисления — не та область, где ярко проявляются достоинства функционального программирования.

Наличие стройной математической основы обеспечивает возможность широкого использова­ния алгебраических методов композиции, преобразования, исследования и верификации программ.

Эффективность реализации функциональных языков на традиционных ЭВМ в области сим­вольных вычислений, во многом благодаря работам Т.Джонссона и Л.Аугустссона из Ґетеборга, приближается к эффективности реализации процедурных языков, несмотря на то, что модель вычислений по функциональной программе и семантика машинного языка кардинально различны.

Кроме преимуществ аппликативных языков как языков программирования, они также при­влекательны в качестве средств описания семантики других языков, а также в роли средств проектирования программных комплексов.

Установлено, что императивные языки по своим возможностям несколько уже аппликативных.

Самым первым функциональным языком явился LISP (List Processing — обработка списков), разработанный и реализованный группой авторов под руководством пионера в области искус­ственного интеллекта Дж.Маккарти в Массачусетском технологическом институте в 1959 г. Цель его создания состояла в удобстве обработки символьной информации. Существенная черта LISP'a — предельная унификация программных структур и структур данных (выражения записываются в виде списков). Этот язык является вторым по возрасту (после Fortran'a) языком программи­рования, широко используемым в настоящее время, и рассматривается специалистами как основной язык программирования систем искусственного интеллекта.

LISP непрерывно совершенствовался и сейчас существует множество развитых его версий с превос­ходной средой программирования, среди которых особо следует отметить INTERLISP и Common LISP.

В настоящее время имеется целый спектр машин для аппаратной поддержки языка LISP. Среди них — LISP-микропроцессор для военных приложений.

LISP послужил стартовой площадкой для разработки языков PLANNER и CONNIVER, которые используются для реализации процедурных моделей знаний.

Сейчас известно множество функциональных языков, значительно более мощных, чем LISP. Наиболее интересны и проработаны среди них ML (Milner Language) Милнера и Miranda Д.Тернера. Нам больше импонирует последний из-за его стройности и простоты. Перечислим особенности этих языков в сравнении с LISP'ом:

1) простота использования функций высших порядков;

2) подстановка аргументов функций в них производится не по значению, а по необходимости (последняя интегрирует достоинства подстановки по значению и по наименованию, что позволяет повысить быстродействие программ и манипулировать с потенциально бесконечными объектами);

3) описание функции представляется не единственным равенством (правилом, уравнением), а совокупностью условных равенств, накладывающих различные ограничения на структуру аргу­ментов, что ведет к повышению компактности и наглядности программ. При вызове функции автоматически осуществляется выбор того или иного правила в соответствии с аргументами и декомпозиция последних;

4) реализация функциональной трактовки ввода-вывода и работы с файлами (в том числе с базами данных), что обеспечивается «ленивой» семантикой (подстановкой по необходимости);

5) поддержка абстрактных типов данных;

6) хороший синтаксис;

7) непротиворечивость в математическом смысле (противоречивость LISP'a хорошо известна, что затрудняет его параллельную реализацию).

С аппликативными тесно связаны языки машин потока данных. Среди последних известность приобрели VALID, VAL, ID и LUCID, причем по LUCID опубликовано полномасштабное руководство.

Разработка аппаратных и программных средств функционального программирования вошла составной частью в проекты ЭВМ пятого поколения.

Таким образом, функциональное программирование по сравнению с императивным, по крайней мере, в области символьных вычислений, имеет преимущества как с точки зрения пользователя, так и с точки зрения реализации (благодаря параллелизму).

В 1987 г. фирма IBM объявила о своей поддержке, языка Common LISP и закупила на него все права. В связи с этим можно считать, что он уже стал стандартом языка LISP.

На ПЭВМ в настоящее время из функциональных языков широко используется только LISP и доступен Scheme («чистое» подмножество LISP'a, т.е. язык без императивных включений). Известны следующие их реализации для DOS:

1) система PC Scheme фирмы Texas Instruments, базирующаяся на компиляции;

2) система LISP компании Microsoft, также основанная на компиляции;

3) система LISP фирмы Norell, базирующаяся на интерпретации;

4) система Mulisp компании Software Ware House, поддерживающая ограниченный диалект LISP'a и основанная на интерпретации;

5) система Mulisp 85 фирмы Microsoft, основанная на интерпретации;

6) система IQ LISP компании Integral Quality, также основанная на интерпретации;

7) среда Byso Lisp фирмы Levien Instrument, включающая:

интерпретатор Byso Lisp 1.17, совместимый с LISP 1.5, MACLISP и Common LISP;

— компилятор Byso Lisp 2.17;

— текстовый редактор;

— структурный редактор, обеспечивающий графическое отображение программ;

— средства печати программы в различных режимах, в частности, в режиме структуризации текста;

8) система Golden Common LISP.американской фирмы Gold Hill Computers, поддерживающая несколько усеченный вариант языка Common LISP.

Для Macintosh OS существует система программирования Macsheme, удовлетворяющая тре­бованиям стандарта Scheme.

Развитые версии LISP'a, в том числе Common LISP, поддерживаются в среде ОС UNIX.

Для эффективной работы с системой функционального программирования необходима мощная ПЭВМ, так как ресурсоемкость таких систем значительна.

Логическое программирование

За исключением нескольких результатов, логика и программирование долгое время были непересекающимися областями исследований. Еще в 1936 г. Тьюринг показал, что любая вычислимая функция может быть вычислена посредством дедукции (вывода) в исчислении предикатов первого порядка, существующий вариант которого построен Г.Фреге в 1879 г. Однако этот результат не нашел практического применения, так как не был известен алгоритм установления общезначимости (истинности во всех интерпретациях) логической формулы. К тому же было показано, что эта проблема алгоритмически неразрешима. В 1930 г. Френч и Эрбран независимо доказали фунда­ментальную теорему, предоставляющую алгоритм, который способен установить общезначимость логической формулы, если она является таковой. В противном случае этот алгоритм зацикливается. Поэтому проблему установления общезначимости в исчислении предикатов первого порядка стали считать полуразрешимой. Разработанный алгоритм также не нашел практического приме­нения вследствие большой его трудоемкости.

В 1962 г. Робинсон предложил метод резолюции, который обладает существенно меньшей трудоемкостью, чем алгоритм Эрбрана, однако все еще не решает проблему комбинаторного взрыва. В этом методе используется единственное мощное правило вывода вместо множества правил, предложенных логиками. Метод резолюции стал применяться в автоматическом дока­зательстве теорем. Одновременно предпринимались усиленные попытки поиска стратегий вывода, сокращающих пространство поиска. На этом пути были достигнуты заметные успехи.

Основываясь на полученных к тому времени результатах, французский ученый А.Кольмероэ создал язык программирования PROLOG (PROgramming in LOGic — программирование в терминах логики), первоначально предназначенный для работы с естественными языками, и опубликовал его описание в 1973 г. Значительного сужения пространства поиска удалось достичь за счет использования логической системы Хорна, являющейся частью исчисления предикатов, и линейной по входу стратегии резолюции. Но даже при таких ограничениях оказалось возможным представлять любую вычислимую функцию. (Заметим, что логика Хорна шире теорий реляционных баз данных.) Большое значение в становлении, развитии и осмыслении PROLOG'a имели работы Р.Ковальского.

Появление PROLOG'a открыло новую область исследований — логическое, или реляционное, программирование, где практические результаты зачастую предшествуют их теоретическому осмыс­лению и обоснованию.

Центральным понятием в логическом программировании является отношение. Программа представляет собой совокупность определений отношений между объектами (в терминах условий, или ограничений) и цели (запроса). Процесс выполнения программы трактуется как процесс установления общезначимости логической формулы, построенной из программы по правилам, установленным семантикой того или иного языка. Результат вычисления является побочным продуктом этого процесса. В реляционном программировании нужно только специфицировать факты, на которых алгоритм основывается, а не определять последовательность шагов, которые требуется выполнить. Это свидетельствует о декларативности языков логического программиро­вания. Она метко выражена в формуле Р.Ковальского: «алгоритм=логика + управление».

В настоящее время известны и другие языки логического программирования.

Языки логического программирования характеризуются:

— сверхвысоким уровнем;

— жесткой ориентацией на символьные вычисления (числовая обработка затруднена);

— возможностью инверсных вычислений (переменные в вызовах «процедур» не делятся на входные и выходные), что является уникальной чертой реляционного программирования, хотя недавно разработан аналогичный подход и для функциональных языков;

— зачастую логической неполнотой в двух аспектах: невозможностью выразить в программе определенные логические конструкции, а также невозможностью получить из программы все правильные выводы.

К сожалению, инверсность вычислений больше декларируется, чем обеспечивается, что вызвано различными усовершенствованиями, делающими языки эффективнее, но разрушающими логи­ческую семантику программ.

Логические программы отличаются принципиально низким быстродействием, так как вычис­ления осуществляются, методом проб и ошибок (посредством поиска с возвратами), а также высокой степенью параллелизма. Однако организация параллельного исполнения затруднительна; сам же параллелизм требует чрезвычайно много ресурсов ЭВМ вследствие недетерминизма и поэтому считается «необузданным». Кроме того, один из основных механизмов реляционного программирования — унификация — имеет последовательную природу.

Таким образом, языки логического программирования являются достаточно мощными, но неэффективными, с точки зрения реализации, языками.

Тем не менее языки логического программирования играют центральную роль в проектах ЭВМ пятого поколения. Уже разработан и разрабатывается ряд архитектур с целью аппаратной поддержки реляционного программирования.

В настоящее время для ПЭВМ существует около пятнадцати реализаций PROLOG'a. Компи­ляция, хотя она и затруднена из-за большого семантического разрыва языка и ПЭВМ, предус­матривается в следующих трех, функционирующих в среде DOS, системах: Arity/Prolog 5.0 фирмы Arity, Turbo Prolog 2.0 фирмы Borland International и Prolog-2 английской компании Expert Systems. Остальные же системы обеспечивают только интерпретацию PROLOG-программ. Prolog-2 усту­пает системе Arity/Prolog по ряду показателей, ни в чем его не превосходя. Однако есть вариант • системы Prolog-2 для Windows 3.0.

Наиболее удачными системами считаются Arity/Prolog 5.0 и Turbo Prolog 2.0, оформленные в виде интегрированных сред. Небольшие разработки, видимо, лучше осуществлять при помощи Turbo Prolog'a, в то время как при работе с большими программными проектами лучше исполь­зовать Arity/Prolog, поскольку он включает более эффективный отладчик. Однако при необхо­димости осуществить компиляцию, а не интерпретацию, придется выйти из интегрированной среды и вызвать автономный компилятор. Входной же язык компилятора является всего лишь подмножеством входного языка интерпретатора. Эта система позволяет компилировать программы непосредственно в среде. Эта система содержит графические средства, а Arity/Prolog их не имеет. Остальные характеристики рассматриваемых двух систем примерно одинаковы.

К сожалению, работы по Turbo Prolog'у фирмой Borland International заморожены.

Интересен также модульный вариант Prolog'a MPROLOG, разработанный в Венгрии. Его реализация ресурсоемка и поэтому он воплощен в систему программирования только для ПЭВМ на МП 80386(SX) и старше.

Объектно-ориентированное программирование

Прототипом объектно-ориентированного программирования послужил ряд средств, содержа­щихся в языке SIMULA-67. Но оформилось оно в самостоятельный стиль программирования в связи с появлением языка SMALLTALK, первоначально предназначенного для реализации функций машинной графики и разработанного А.Кеем. Первая версия этого языка создана в 1972 г. С тех пор построено несколько его версий.

Корни объектно-ориентированного программирования уходят в одну из ветвей логики, в которой первичным считается не отношение (как для логического программирования), а объект. По сравнению с исчислением предикатов объектно-ориентированные логические системы об­ладают более сложными синтаксисом и правилами вывода. С объектно-ориентированным про­граммированием тесно связана теория акторов.

Основными особенностями объектно-ориентированных языков являются:

1) наличие активных объектов (акторов);

2) формирование объектов путем наследования свойств;

3) посылка сообщений от объекта к объекту как механизм организаций вычислительного процесса.

Суть данного стиля программирования выражается формулой «объект=данные + процедуры».

Итак, объект интегрирует некоторое состояние (или структуру данных) и доступные только ему механизмы изменения этого состояния Для того чтобы модифицировать состояние некоторого объекта, необходимо послать ему соответствующее сообщение. Действие (или метод), выполняемое (выполняемый) адресатом сообщения, касается только его самого: другие объекты не должны знать, каким образом данный объект реализует ту или иную функцию. Объединение данных и процедур в объекте называется инкапсуляцией, и это свойство неотъемлемо присуще объектно-ориентированному программированию. Многие развитые объектно-ориентированные языки программирования (Turbo Pascal, С++) обладают наряду с этим полиморфизмом, т.е. возможностью использования методов с одинаковыми именами для работы с данными различных типов.

Концепция объекта опирается на методы структурного программирования и методы разработки программ, основанные на абстракции данных.

Структурное программирование связано с функциональной декомпозицией и предполагает проектирование программного продукта «сверху вниз». Однако такой метод не позволяет учесть зависимость архитектуры программы от структур данных, которые ей придется обрабатывать.

Использование подхода, основанного на абстракции данных, ведет к противоположному эффекту: разработка программы осуществляется «от данных», а упор делается на выборе способа их представления. В этом случае, естественно, образуется разрыв между структурами данных и процедурами их обработки.

Объектно-ориентированное программирование позволяет ликвидировать противопоставление прощ \ур данным и их неравноправность, свойственные двум описанным подходам, и одновре­менно с этим интегрирует достоинства рассмотренных методов разработки программ. Таким образом, объектно-ориентированное программирование поддерживает качественно новый уровень совместной структуризации данных и процедур их обработки.

Многие объектно-ориентированные языки имеют средства для объединения объектов в классы. Объекты принадлежащие одному классу, называются его примерами. Это позволяет хранить процедуры (в терминах объектно-ориентированного программирования методы), применимые ко всем примерам класса, в единственном экземпляре, только в соответствующем классе. Данный подход имеет очевидные преимущества: код размещается только в одном месте, чем экономится память и обеспечивается модифицируемость программы.

Ряд языков, включая SMALLTALK-80, С++, Turbo Pascal и Objective-C, развивают это понятие счет того, что классы размещаются в узлах дерева наследования (свойств). Таким образом строится иерархия классов. При этом пример наследует свойства (процедуры-методы) своего класса, а также всех суперклассов этого класса. Методы, определенные в классе-корне дерева, наследуются всеми классами и их примерами. Наследование наряду с инкапсуляцией и полиморфизмом является важнейшим свойством объектно-ориентированного программирования.

Механизм наследования с древовидной структурой в определенной степени ограничен, так как во многих случаях разделение свойств в соответствии со строгой иерархией не может быть достигнуто. Поэтому некоторые языки допускают классы, которые наследуют свойства более чем одного непосредственного суперкласса, в результате чего иерархия классов становится направленным ациклическим графом, а не деревом. Такой механизм добавлен в качестве рас­ширения в SMALLTALK. Подобные механизмы доступны также в основанных на LISP'e объектных системах Flavours, CommonLoops и GLOS.

Описанная модель дискретных объектов, взаимодействующих друг с другом, является хорошей основой для параллелизма. В зависимости от конкретизации объектно-ориентированной модели вычислений существуют три различных подхода к распараллеливанию. Наиболее перспективен из них следующий. Объект (называемый в данном случае актором), посылающий сообщение, не ждет ответа от своего адресата, а продолжает функционирование. Поэтому сообщения должны быть способны становиться в очередь к адресату. Одновременно может быть активизировано много акторов, причём все вычисления выражаются, главным образом, в терминах их коммуникаций. В этом случае накладные расходы на каждый процесс будут малы, вследствие чего даже небольшие объекты могут быть совместно исполняемыми, что и обеспечит наилучшую степень параллелизма Языками данного класса являются система Astra, а также Act 1 и Act 3. В простейшем случае посылка сообщения эмулируется вызовом метода в том или ином объекте как процедуры.

SMALLTALK системы обладают высокой мобильностью, так как в них первоначально осуществляется компиляция программы на промежуточный язык, а затем — интерпретация кода на этом языке.

Разработан язык Concurrent SMALLTALK, добавляющий асинхронные посылки сообщений к уже имеющимися в SМALLTALK'е синхронным, что обеспечивает лучший параллелизм.

Объектно-ориентированные языки находят применение, главным образом, при построении мо-делей, в том числе при создании языков представления знаний и реализации протоколов вычис­лительных сетей. Потенциальные же возможности объектно-ориентированных языков гораздо шире.

Разрабатываются архитектуры ЭВМ для данной парадигмы.

Этот стиль программирования характеризуется богатыми графическими возможностями и средой программирования, развитой модульной структурой программ, но порою невысокой эффек­тивностью реализации языков на непараллельных ЭВМ.

На модульности следует заострить особое внимание: именно она упрощает разработку сложных программных продуктов, а также облегчает их комплексирование, модификацию и сопровождение.

Интерес к объектно-ориентированному программированию в настоящее время быстро растет, что объясняется и что отчасти явилось причиной появления систем программирования Turbo Pascal 5.5 и 6.0, Turbo С++, а также BORLAND С++.

На ПЭВМ доступны следующие SMALLTALK-системы:

  1. Smаlltalk /V фирмы Digital для DOS;

  2. Smalltalk-80 компании Apple Computer для Aplle DOS;

  3. Smalltalk-80 фирмы Softsmarts для DOS;

  4. Smalltalk-PC компании Software Systems для DOS;

  5. Smаlltalk /V РМ для OS/2 PM;

  6. Smalltalk-АТ с графическим интерфейсом и поддержкой "мыши" (для DOS);

  7. Smalltalk/Object фирмы ParkPlace для OS/2 PM.

Для Windows 3.0 фирмой The Whitewater Group предлагается объектно-ориентированная система программирования Actor.

Известна также система С_talk для DOS, интегрирующая С и Smalltalk. Другие варианты интеграции процедурного и объектно-ориентированного программирования уже рассматривались в подпункте "Процедурное программирование" данного пункта.

В последнее время большой интерес проявляется к языку С++, созданному в 1983 г. Строустрапом. Этот язык совместим снизу вверх с ANSI-стандартом С, обладает в отличие от С жёстким контролем типов и является достаточно сложным языком.

В данном пункте практически не затронуты вопросы интеграции различных стилей программирования. Однако это не означает отсутствия таких работ и многообещающих их результатов. Дело в том, что практически неизвестны коммерческие программные продукты такого типа для ПЭВМ, за исключением уже упомянутых. Тем не менее имеется интегрированная среда программирования XSimp 2.0, поддерживающая все 4 рассмотренные парадигмы программирования, обладая при этом функциональным акцентом. Данная система открыта для расширений и предлагается на отечественном рынке. Имеются её реализации для DOS и Macintosh.