Показаны сообщения с ярлыком Идеи. Показать все сообщения
Показаны сообщения с ярлыком Идеи. Показать все сообщения

пятница, 5 сентября 2008 г.

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

В августе позволил себе короткий отпуск и взял с собой книгу Страуструпа Дизайн и эволюция языка C++. Вроде, в свое время читал ее (просматривал), но в этот раз обнаружил совершенно замечательный раздел, который раньше как-то прошел мимо меня. Он пишет в точности о том, что сейчас занимает все мои "профессиональные" мысли!


Не поленюсь и выпишу раздел целиком, выделяя курсивом и жирным шрифтом некоторые "ударные" с моей точки зрения места. А мои комментарии - красным.

9.4.4 За пределами файлов и синтаксиса

Как я вижу среду для разработки программ на С++? Прежде всего - инкрементная компиляция. Если вносится небольшое изменение, то система "понимает", что оно небольшое, и генерирует новую версию программы мгновенно. Моментальные ответы хотелось бы получать также на простые вопросы и указания типа: "Показать объявление f", "Какие еще f есть в области действия", "Как разрешен этот вызов оператора +?", "Какие классы произведены от Shape?" и "Какие деструкторы вызываются в конце этого блока?"

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

В программе на С++ есть много информации, которая в типичной среде доступна только компилятору. Уверен, что она должна быть предоставлена программисту.

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

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

                           Прекрасно! Это в чистом виде семантический взгляд на программу!
                           Если появится система, которая в полной мере воплотит такой
                           подход к работе с С++, это будет весьма существенным прогрессом,
                           если не сказать прорывом... Продолжая тему "семантического"
                           подхода к С++, эксплуатируемому Интерстроном, могу сказать, что
                           у нас есть и реальное средство, работающее с семантическим
                           представлением: это визуализатор, который показывает исходную
                           программу в виде дерева семантических элементов - именно как 
                           "набор типов, функций, предложений..." и/или в нотации UML.

То, что в основе реализаций С++ лежат символьно-ориентированные инструменты, всегда было главным препятствием на пути развития языка. Если нужно препроцессировать и перекомпилировать каждый заголовочный файл, прямо или косвенно включенный в файл, где находится слегка измененная функция, то для этого требовалось определенное, пусть и небольшое время. Существует несколько методов, позволяющих избежать ненужных перекомпиляций, но, по-моему, наиболее перспективный и интересный подход - отказаться от традиционного исходного текста и положить в основу инструментов абстрактное внутреннее представление. Ранний вариант такого представления можно найти в работах [Murray, 1992], [Koenig, 1992].  Естественно, текст все равно необходим - его вводят и читают пользователи - но он легко преобразуется системой во внутреннюю форму

                           Ну, насчет "легко" - это он погорячился. :-) Если то абстрактное
                           внутреннее 
представление, о котором он говорит выше, содержит
                           семантическую информацию 
об исходной программе, введенной
                           в текстовом виде, то построение
такого представления - весьма
                           нетривиальнная задача. Но крайне... challenging, как 
говорят у них.

и реконструируется по запросу.

                           А вот реконструкция текста - это действительно несложно.

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

Нетекстовое представление могло бы быть создано языками более высокого уровня, генераторами программ, инструментами визуального программирования и т.д.

                           Ну, и обычными компиляторами переднего плана, разумеется.

Это позволило бы таким инструментам работать в обход обычного синтаксиса С++ и даже помогло бы избавить язык от некоторых неудачных особенностей его синтаксиса. Я утверждаю, что система типов и семантика С++ чище, чем его синтаксис.

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

                           Более того: такое описание я как раз сейчас делаю. И должен сказать,
                           что 
получаю громадное удовольствие, на каждом шаге наглядно
                           наблюдая, 
как обсыпаются многочисленные корявые и громоздкие
                           синтаксические 
конструкции языка, обнажая естественное и стройное
                           здание 
семантики С++...

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

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

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

Единственная фудаментальная константа - это базовая семантика языка. Она не должна меняться ни при каких обстоятельствах, и, учитывая это, вполне можно выдать С++-код в обычной текстовой форме по запросу.

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

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

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

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

вторник, 6 ноября 2007 г.

"Древовидный" C++

Сергей Прохоренко в комментарии написал:

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

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

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

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

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

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

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

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

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

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

(Между прочим, редактор Visual Studio включает элементы «древовидного» подхода – фрагменты текста программы, соответствующие отдельным синтаксическим конструкциям, можно избирательно сворачивать и разворачивать. К сожалению, набор языковых конструкций, управляемых редактором, ограничивается пространствами имен, классами, функциями и комментариями и не распространяется на «внутренности» функций. Скорее всего, нечто подобное и в Эклипсе есть; может, даже и получше, чем в VS?)

понедельник, 18 июня 2007 г.

Несколько предварительных замечаний

амый первый пост - просто в качестве проверки и как бы предисловия. Начну с цитаты из одной своей давней статьи ("Редкая профессия"):

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

Это совсем не самореклама (что рекламировать-то - мало ли кто чего программирует?), а просто чтобы было понятно, чем я занимаюсь. А кроме компиляторов (и интерпретаторов, и всяких языко-ориентированных тулзов и прочего подобного) я, строго говоря, делать ничего и не умею. Ну, разве что лекции читать, да статьи писать.

Так что в этом блоге (если, конечно, времени хватит и если запал не исчезнет) я буду писать строго в рамках очерченных предметов. Если быть более точным, то вот темы, которые мне интересны:

- Компиляторы языков высокого уровня, в основном их "фронтальные" части. Генерация кода и оптимизация тоже интересны, но не настолько. Да и сказать что-то умное по этому поводу мне заметно сложнее, чем некоторым моим друзьям и коллегам. (Надеюсь, они будут иногда захаживать сюда :-)). Инструменты генерации синтаксических распознавателей (прежде всего, Yacc/Bison и COCO).

- Императивные языки как таковые. C/C++, Ada, C#, Java, Oberon/Zonnon, Eiffel (порядок перечисления случаен). Стандартизация языков, развитие языков. Современные инфраструктуры исполнения, прежде всего Java/JVM и Microsoft.NET/CLR/MSIL. Собственно виртуальные машины (на техническом уровне) - предмет особого интереса.

- Семантические интерфейсы (хороший и почти единственный из реальных пример - интерфейс ASIS для языка Ada). В особенности интересует все, что относится к "плюсам". Есть несколько старых проектов для C++ в этой сфере (успешно канувших в Лету, к сожалению, Sage++, например), если удастся найти что-то свежее - обязательно напишу. К этой теме непосредственно относится понятие промежуточного представления программ. Я, правда, предпочитаю название "семантическое представление" - об этом тоже надо будет подробнее написать, для меня это очень важная тема.

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

- Функциональные языки. Наверное, придется ограничиться Lisp/Scheme как наиболее концептуально чистыми. Речь идет как о языках и функциональной парадигме как таковых, так и об инструментах. Один из первых постов будет об идее реализации Lisp для .NET.

- Продвинутые архитектуры компиляции, прежде всего, с ориентацией на глубокую интеграцию компиляторов и сред разработки. В 2005 году на эту тему даже статью написал, правда, вполне поверхностную. А тема сама по себе крайне интересная, да и реальные системы есть (как предмет анализа и образец) - прежде всего, Visual Studio и Eclipse.

Ну вот, примерно так... Потом, может, еще чего добавлю. Вообще-то, далеко не все упомянул. Проект ONBASS, в котором я сейчас, вроде бы, участвую (по договору с London Metropolitan University), вообще о другом, но тоже интересном. Потом как-нибудь.

Да, а та статья, цитату из которой я привел в начале, оказывается, исчезла с сайта PC Magazine/Russian Edition. Архив номеров за 1997 год просто отсутствует. А может, не нашел? Журнал был за номером 12, кажется (спецвыпуск, с медведем на обложке).

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

А если дело совсем хорошо пойдет, то... продолжение напишу! За десять-то лет столько всего интересного произошло, уж вы поверьте... :-)