пятница, 22 мая 2009 г.

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

На RSDN ввязался в дискуссию по поводу параллельного программирования и вставил там свои пять копеек на счет SObjectizer-а. После чего возник спор о том, является ли программирование с использованием SObjectizer кошмаром или нет (вот его начало). Резюмируя, суть претензий к SObjectizer можно свести к двум пунктам:

  1. SObjectizer заставляет разработчика сводить все сценарии работы агентов к явному конечному автомату. Что плохо для сценариев, в которых агенты должны делать синхронные запросы друг к другу. Т.е. послал агент A агенту B какой-то запрос и тут же “заснул” в ожидании ответа. Когда ответ пришел, его разбудили и он продолжил работу с той же точки. Причем все это выполняется в рамках одной функции агента A, с сохранением промежуточного состояния агента на стеке. Это модель взаимодействия легких процессов в Erlang. Так же она, насколько я понимаю, является обычной для языков со встроенной поддержкой продолжений (continuations). В SObjectizer-4 такая схема работы невозможна. В SObjectizer-4 агент A должен будет отослать сообщение агенту B сообщение и завершить обработку своего текущего события. Когда агент B пришлет ответ, у агента A сработает другое событие. Это означает, что свое промежуточное состояние агент A должен будет хранить не на стеке, а в своих атрибутах.
  2. SObjectizer-4 слишком многословен. По словам моего оппонента, многословность является следствием пункта номер 1.

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

А вот пункт второй действительно является болезненной темой. Во-первых, самому хотелось бы писать меньше кода при работе с агентами (хотя тут интересный момент есть: в более-менее серьезных агентах объем SObjectizer-овских описаний занимает очень небольшой объем по сравнению с прикладным кодом). Во-вторых, мне кажется, что объем кода в простых примерах (типа Hello, World) создает незаслуженное отрицательное впечатление о SObjectizer у новичков.

Поэтому устранение многословности SObjectizer является одной из главных целей разработки SObjectizer-5. И я вижу пока всего два взаимоисключающих пути достижения этой цели. Первый путь – это использование внешних DSL. По аналогии с тем, как используются IDL для описания интерфейсов, ASN для описания структур данных и пр. Лично мне этот путь кажется наиболее многообещающим. Но он встречает серьезное неприятие у других заинтересованных в SObjectizer разработчиков. Поэтому рассматривается и второй путь – использование только средств C++.

Как раз в попытке придерживаться второго пути пару месяцев назад у меня возникли мысли о том, как же описание агента могло бы выглядеть в SObjectizer-5. С использованием только простых возможностей C++ (как у некоторых есть предубеждения против внешних DSL, так же у меня есть предубеждение против навороченных шаблонных конструкций). Как мне казалось до вчерашнего дня, идеи были достаточно привлекательными.

Но вчера, по следам RSDN-овского спора, я решил сравнить, а какой выигрыш даст новая схема описания агентов по сравнению с существующей схемой. Вот результат для реального агента. Далеко не самого сложного. Итог не радует:

Никакого выигрыша. Более того, мне кажется, что в новом варианте дублирования кода даже больше, чем в существующем.

Да, новый вариант строже типизирован. Да, значительная часть ошибок будет вылавливаться компилятором. И бла-бла-бла. Но с точки зрения сокращения писанины результат удручающий.

Значит, нужно что-то править в консерватории. И я склонен еще более серьезно рассматривать варианты с внешними DSL. Не важно, будет ли этот DSL базироваться на Ruby или же это будет специализированный синтаксис и C++ный транслятор. Но нужно, чтобы описание агента было максимально простым и компактным. А весь необходимый оберточный C++ный код генерировался бы автоматически, без вмешательства со стороны программиста.

В этой связи вопрос к читателям (которым хватило интереса и терпения дочитать до этого места): если у вас есть предубеждения против использования внешних DSL (не важно, IDL, ASN, описаний для Google Protobuf, WSDL и пр.), то поделитесь, пожалуйста причинами возникновения ваших предубеждений.

Отправить комментарий