Языки программирования. Прошлое и будущее. С.Бобровский (1012869), страница 9
Текст из файла (страница 9)
Все! На этом описание языка почти заканчивается. Конечно, есть еще переменные и возможность работы с адресами. Однако без наличия структур, позволяющих вычленять управляющие последовательности команд в отдельные модули, например в подпрограммы, язык программирования существовать не может. Форт содержит оригинальные средства, позволяющие гибко и наглядно описывать структуру решаемой задачи.
Любой последовательности команд можно поставить в соответствие «слово» — обычный идентификатор. Например, вышеприведенные команды можно «обозвать» СЛОЖ_ДЕЛ с помощью такой строки:
: СЛОЖ_ДЕЛ + / ;
Слово СЛОЖ_ДЕЛ записывается в специальный словарь Форт-системы и становится доступным для дальнейшего использования наряду с обычными командами. Для достижения большей эффективности это «слово» может быть откомпилировано. Так можно легко описывать довольно сложные процессы вычислений, группировать их в слова и затем работать уже только с ними, зная, какие действия со стеком они выполняют. Например, управляющие команды для процессора микроволновой печи можно задать в таком виде:
температура 200 объект курица жарить
Форт-системы обычно очень компактны. Ядро занимает 10-15 Кбайт (!), а получающийся код по объему и эффективности не уступает ассемблеру.
Но есть, конечно, у Форта и недостатки, причем они оказались настолько существенными, что чаша весов при выборе языка, способного заменить ассемблер, быстро склонилась в сторону С. Основная проблема заключается в сложности восприятия текста, записанного в обратной польской форме, и, соответственно, в трудоемкой отладке. Чем дальше язык отходит от привычной для человека формы описания алгоритма, тем тяжелее с ним работать и тем больше ошибок возникает на этапе разработки. Язык Форт позволяет создавать очень эффективные программы, но с появлением быстродействующих компьютеров скорость работы и тем более небольшие объемы памяти, занимаемые программой, практически перестали играть важную роль. На первый план вышли языки, обладающие максимально выразительными средствами.
Сегодня Форт используется преимущественно для программирования микропроцессоров, где его качества проявляются наиболее выгодно. Такая ниша довольно объемна, и Форт уверенно чувствует себя в ней. Этот факт, в частности, подтверждают несколько стандартов языка, обновляемых с завидной регулярностью. Скорость обновления диктуется самой идеологией Форт-системы, как переносимого и не зависящего от платформы продукта. Американский национальный стандарт описывает версию ANS Forth, такие компании, как IBM, HP, Sun, Apple и другие, поддерживают стандарт IEEE 1275 от 1994 года.
Форт не только не сдается, но даже пытается бороться со своим главным конкурентом — языком С. Существуют специальные трансляторы из С в Форт, причем их создатели утверждают, что код, преобразованный из С в Форт, для большинства вычислительных задач работает значительно быстрее! Имеются, соответственно, и обратные трансляторы, из Форта в С, но об эффективности подобных преобразований их разработчики предпочитают не распространяться.
Как это бывает практически со всеми необъектными языками, родившимися достаточно давно, рано или поздно в них пытаются добавить понятие объекта. Но если в одни языки это понятие вписывается органично, как, например, в Аду, то в Форте эти попытки привели к потере гибкости и не получили большого распространения.
Бесплатных версий Форта в мире довольно много. Информацию о них можно найти на сайте www.forth.org. Из коммерческих версий Форта можно выделить кросс-платформный вариант SwiftForth (www.forth.com). Вообще, множество версий языка Форт практически для всех мыслимых платформ объясняется максимальной простотой языка. Вы можете найти Форт для Windows и OS/2, для компьютеров Amiga и Macintosh, для систем Sun и так далее. И стоят они недорого — от 100 до 300 долларов.
Для ряда задач, где требуется действительно быстрая переработка и анализ числовой информации, Форт пока незаменим, так как относительная простота языка в сочетании с его гибкостью и широкой распространенностью позволяют решать эти задачи очень эффективно, не прибегая к ассемблеру.
Пропел ли Пролог свою «лебединую песню»?
Пролог по праву считается одним из наиболее ярких языков программирования. Заложенная в него концепция логического программирования с годами только набирает популярность.
В отличие от подавляющего большинства других языков Пролог (Prolog) обычно рассматривается в одном контексте с понятием «логическое программирование». Сторонники этого направления считают. Что человек должен не задавать компьютеру последовательность команд на некоем ориентированном на компьютер языке, а описывать саму задачу в абстрактных логических терминах, не оперирующих определениями «байт» или «указатель». Иными словами, надо создать своего рода модель анализируемой проблемы и попытаться получить положительные или отрицательные результаты этого анализа.
У многих людей, знакомых с логическим программированием, обычно возникают ассоциации с японским проектом компьютеров пятого поколения, все программное обеспечение которых создавалось на базе Пролога. Некоторые эксперты считают, что этот проект фактически провалился, и причиной этому послужили некоторые присущие Прологу функциональные ограничения (хотя это не так — см. главу «Как японцы компьютерный мир осчастливили»).
Строго говоря, Пролог не является языком программирования в чистом виде. С одной стороны, это оболочка экспертной системы, с другой — интеллектуальная база данных, и, что самое важное, не реляционная. Математическая модель, лежащая в основе Пролога, довольно сложна, и по мощности системы формирования запросов к базе с этим языком не сравнится ни одна из коммерческих СУБД.
Фактически Пролог является не процедурным, а декларативным языком. Человек лишь описывает структуру задачи, а «внутренний мотор» Пролога сам ищет решение. Более того, в языке вообще не существует понятия последовательности команд — она скрыта в математической модели языка. Хотя, конечно, небольшой список «линейных» операторов типа repeat присутствует, но он ограничен возможностями использования лишь для конкретных случаев.
Математическая модель Пролога основана на теории исчисления предикатов, в частности, на процедурной интерпретации Хорновых дизъюнктов (содержащих не более одного заключения) Роберта Ковальского из Эдинбурга. Ее в алгоритмическом, машинно-ориентированном виде, выразил коллега Ковальского Маартен ван Эмден. Надо сказать, что работы этих ученых из-за большой сложности их практической реализации на компьютерах (по тем временам) подвергались большой критике со стороны американских специалистов по искусственному интеллекту.
Автор языка Пролог Алан Колмероэ начал работу над полноценной компьютерной реализацией трудов Ковальского в 1972 году во французском университете Марсель-Экс. Он составил алгоритм формальной интерпретации процесса логического вывода и разработал систему автоматического доказательства теорем, которая была написана на Фортране. Она-то и послужила прообразом Пролога. Название языка произошло от Programmation en Logique — ЛОГическое Программирование. Говорят, что придумала это название жена Алана. В первое время, в начале 70-х годов, Пролог был не очень популярен. Как и Лисп, он пребывал в забвении, вызванном отсутствием хороших реализаций. Но вскоре появились первые компиляторы с этого языка. В частности, прекрасная реализация Дэвида Уоррена для компьютера DEC-W в Эдинбурге стала своего рода стандартом, сохранившимся до сегодняшнего дня. Эффективность этой версии заставила специалистов по искусственному интеллекту по-новому взглянуть на Пролог. В некоторых приложениях, типичных для Лиспа, таких как обработка списков, Пролог уже не уступал своему конкуренту. В дальнейшем это стимулировало ряд специалистов по логическому программированию к переходу на использование Пролога.
В качестве типовых данных Пролог использует элементарные единицы данных, так называемые атомы: строки символов и числа. Из атомов составляются списки и бинарные деревья. Сама «программа» строится как последовательность фактов и правил, а затем формулируется утверждение, которое Пролог будет пытаться доказать с помощью введенных правил.
Таким способом можно описывать очень сложные проблемы, которые система Пролог будет решать автоматически. Для этого используется метод сопоставления и рекурсивного поиска. Вообще рекурсия играет в Прологе не меньшую роль, чем в Лиспе, хотя и носит декларативный характер.
Сразу после появления эдинбургской версии Пролога было успешно осуществлено несколько проектов, которые ранее казались очень сложными для реализации. Появилась возможность создания интеллектуальных нереляционных баз знаний с иерархической структурой на основе стандартного механизма с гибкой организацией очень сложных запросов. Были написаны эффективные программы для решения переборных задач, в частности из области молекулярной биологии и проектирования СБИС, где требовалось учитывать либо сложные внутренние структуры, либо большое число правил, описывающих организацию объекта. Хорошо зарекомендовал себя Пролог в качестве экспертной оболочки. А задачи грамматического разбора прямо-таки просились быть решенными на Прологе. Что весьма характерно, первый высокопроизводительный компилятор этого языка (эдинбургская версия) был написан на самом Прологе! И немудрено, ведь все формальные синтаксические описания грамматик в форме Бэкуса прекрасно записываются в терминах Пролога.
Но в силу своей специфичности и сильной ориентированности на встроенные алгоритмы поиска доказательств Прологу не суждено было воплотиться в конкретном стандарте, который получил бы массовое признание. На сегодня имеется стандарт ISO/IEC 13211-1:1995, но он поддерживается далеко не всеми коммерческими системами, имеющими различные принципы реализации и цели, для которых планируется использовать эти системы. Фактически первым и единственным стандартом осталась версия языка, созданная в Эдинбурге для PDP в 70-е годы! И хотя ее поддерживают не все сегодняшние системы, их разработчики обычно прилагают к своим продуктам препроцессор, переводящий программу данного диалекта к эдинбургскому виду.
Долгое время среди разработчиков языка шла напряженная борьба между сторонниками оригинальной семантики Пролога и специалистами, стремившимися пожертвовать ясной структурой языка ради повышения эффективности реализации. В частности, стала играть роль последовательность правил в базе данных. Дело в том, что для быстрого получения ответа удобно начинать с использования, например, самых простых или самых эффективных с точки зрения человека правил.
Программа на Прологе постепенно стала приближаться к обычным процедурным (последовательным) языкам. Немалую роль в этом сыграло и искусственно введенное понятие отсечения, своего рода аналог столь нелюбимого Дейкстрой оператора goto. Теперь программист мог по своему усмотрению динамически отсекать бесплодные, по его мнению, ветви деревьев перебора, что привело к многократному (в сотни раз) повышению скорости работы программ, но при этом нарушило ясность их структуры и вызвало множество проблем, связанных с отладкой.
В целях получения высокоэффективных исполняемых модулей были предприняты попытки написания компиляторов, транслирующих текст Пролог-программ в код на языке С. Однако, в отличие от процедурных языков сверхвысокого уровня, для Пролога хорошего результата добиться не удалось. Структура декларативной «программы» с большим количеством базовых фактов приводила к появлению крайне неуклюжих конструкций. Например, появлялись операторы switch языка С с более чем 15000 (!) условиями выбора case. Такие синтаксически корректные выражения многие компиляторы считали ошибкой или выдавали неэффективный код.
К счастью, развитие вычислительной техники в сочетании с уникальной структурой языка дало свои результаты. При появлении первых параллельных компьютеров люди, программирующие на Прологе, быстро осознали пагубность различных «нововведений» вроде оператора отсечения, лишавших язык оригинальной чистоты, и вернулись к первоначальной версии языка. Пресловутая последовательность правил перестала играть роль, так как появилась возможность выполнять вычисления параллельно, а в силу того, что математическая теория Пролога не накладывает никаких требований на упорядоченность фактов и правил в базе, скорость работы программы растет пропорционально числу процессоров.
Имеются бесплатные версии Пролога для реализаций на параллельных компьютерах, но они либо усечены до возможности исполнения не более чем на двух процессорах, либо неэффективны. Да и коммерческих параллельных версий не так много. Это, например, Paralogic и Densitron CS Prolog для транспьютеров. Информации по этим версиям очень мало. Впрочем, неплохие общедоступные альтернативы параллельному Прологу предлагаются японцами в рамках проекта вычислительных систем пятого поколения (см. далее).
Сегодня свободно распространяемые версии Пролога для однопроцессорных компьютеров обычно представлены как усеченные подмножества коммерческих продуктов или как версии, бесплатные только для учебных и научных организаций. Кроме того, существует немало диалектов этого языка, весьма сильно отличающихся от оригинала и созданных для конкретных целей. Их обычно можно получить бесплатно.
Для примера приведем систему SWI-Prolog (ftp://swi.psy.uva.nl), содержащую быстрый компилятор, профилировщик, набор библиотек и удобный интерфейс для подключения модулей на языке С. Она реализована для ряда С/шя-платформ, таких как HP и Linux, а также для Windows, NeXT, OS/2, Sun и SPARC.
Несколько лет назад в Пролог было введено понятие объекта. Появился ряд объектных диалектов, таких как freeware-версия OL(P) — Objec: Layer for Prolog. Это простой компилятор объектного кода в обычный Пролог, поддерживающий все принципы объектно-ориентированного программирования, вплоть до множественного наследования. Не обошлось, конечно, и без коммерческих объектных версий, не получивших, впрочем, большого успеха из-за появления нового полудекларативного языка с мощными средствами объектно-ориентированног программирования — Smalltalk.
Из коммерческих реализаций Пролога надо упомянуть бывшую одно время весьма популярной систему Arity Prolog 6.1. Вариант Delphin: Prolog, работающий на ряде Unix-платформ, включает в себя высокс производительные компилятор и интерпретатор, интерфейсные библи I теки и поддерживает эдинбургский стандарт. Для системы Windoi имеется прекрасная 32-разрядная версия LPA-Prolog как со «стандартным», так и с расширенным объектным синтаксисом, с набором бис лиотек для работы с оконным интерфейсом, с поддержкой DDE и пр токола ODBC и с возможностью создания библиотек DLL.