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

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

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

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

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

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

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

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

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

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

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

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

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

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

Недавняя статья Страуструпа

Evolving a language in and for the real world: C++ 1991 - 2006
Ссылка: http://www.research.att.com/~bs/hopl-almost-final.pdf
Статья большая, почти 60 страниц.
Написана для очередной конференции по истории языков программирования.

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

В целом, статья, безусловно, стоит того, чтобы ее внимательно прочитать.

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

C++'s success in real-world use also led to influences that are less beneficial. The frequent use of ugly and irregular C++ style of syntax in modern languages is not something I'm proud of. It is, however, an excellent indicator of C++ influence - nobody would come up with such syntax from first principles.

Удивительно видеть такую трезвую и недвусмысленную оценку «большого стиля» C++ от самого создателя этого языка! И одновременно, с чувством глубокого удовлетворения наблюдать такой классный пинок тем, кто копирует «ugly and irregular style of syntax» из примитивно понятых «маркетинговых» соображений... Все ведь понимают, в чей огород этот камень.

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

понедельник, 5 ноября 2007 г.

XML как замена всему :-)

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


- Авек плезир! - отозвался Фагот, - но почему же
с вами одним? Все примут горячее участие!
(«Мастер и Маргарита»)



А почему же только Лисп? См. второй эпиграф.
А почему только синтаксис? Почему не задавить заодно и семантику? :-)

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



Program ::= List
List ::= '(' { Element } ')'
Element ::= List | Atom


Весь язык, собственно говоря, «перетек» в семантику – в правила интерпретации списков, которые (правила) определяются в зависимости от первого элемента.

Насколько это упрощает/усложняет программирование и чтение Лисп-программ – давайте не будем касаться этого вопроса. Сейчас мне хочется просто отметить интересное сходство Лиспа и... XML.

В самом деле, XML ведь тоже (опять-таки, если не брать во внимание второстепенные технические детали), предельно прост:



XMLDocument ::= Element
Element ::= StartTag { Content } EndTag
Content ::= Element | NonstructuredText


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

У XML, в отличие от Лиспа, нет собственной семантики – это всего лишь язык разметки. Смысл XML-документу придают агенты, его воспринимающие – либо люди, либо программы, с ним работающие. Но отсутствие семантики парадоксальным образом оборачивается невиданным расширением сфер использования: с помощью XML можно описать практически все на свете; главное – договориться, как именно описывать и как понимать/интерпретировать такое XML-описание. Для первого служат DTD, Schema или различные неформальные соглашения, для второго – шаблоны XSLT плюс смежные технологии, а также стандартизованные программные интерфейсы – DOM, SAX и подобные.

Вообще-то писать на эту тему можно очень много, но сейчас я хочу только лишь указать на проект Superx++ (http://xplusplus.sourceforge.net/), интересный как раз попыткой предложить XML как замену синтаксиса всеми нами любимого языка C++.

Собственно, смысл проекта достаточно прост: предлагается нотация, полностью заменяющая синтаксис C++ эквивалентными XML-конструкциями. Правда, более внимательное чтение примеров не подтверждает полной замены: автор не решился «xml-изировать» язык целиком и синтаксис выражений оставил в исходном виде. Более того, в какой-то момент он, похоже, испугался собственного радикализма и предложил некий «промежуточный» вариант под названием shortx, в котором язык переведен в XML-нотацию только частично...

Вот, полюбуйтесь: объявление класса в XML-нотации. Исходное, «плюсовое» объявление легко восстановить.





<class name="XTree">
  <scope type="public">
    <func name="GetSize" type="int">
      <return>
        <eval member="Size" object="this">
      </return>
    </func>
    <var name="Size" type="int">200</var>
  </scope>
</class>




Отметим, что (само)уверенности автору не занимать: одна из его первых статей на эту тему называется так: x++: The World's First Full XML-Based Programming Language Released!

(Сначала язык назывался X++, но это имя оказалось занято более «авторитетными» компаниями, и автору пришлось сменить его на superx++.)

Что касается собственно проекта Superx++, то его реализация не вышла из беты, а с 2004 года он, кажется, не развивается; по правде говоря, трудно представить себе какое-то реальное практическое применение такого парадоксального подхода... В общем, любопытна только идея как таковая, а также некоторые технические подробности; в частности, такая.

Для superx++ автор сделал интерпретатор, причем написал его на плюсах. А почему не попытаться применить для этой же цели XSLT? Это выглядело бы логично: ведь он как бы хочет по максимуму использовать преимущества XML-технологий? Понятно, что автор хотел сделать эффективный инструмент, так как надеялся найти практическое применение своему проекту (даже фирму специально для этого сделал), но мне кажется, исследователькая ценность проекта от такого выбора только бы возросла, при этом совершенно неважно, в какой мере это ему бы в итоге удалось. Даже отрицательный результат здесь был бы очень интересен; по крайней мере, мы бы лучше себе представляли границы применимости шаблонов XSLT. Я, например, давно хочу эти границы применимости почувствовать...
UPDATE: совершенно случайно вдруг увидел старую статью В.Турчина:
Рефал как язык для обработки xml-документов
Валентин Турчин
Опубликовано в журнале "Компьютерра" №25 от 02 июля 2001 года
Ссылка: http://www.computerra.ru/2001/402/10900/

Там, помимо вопросов обработки XML-документов средствами Рефала, обсуждается и вариант XML-нотации для этого языка...