Мультиязычная разработка

топ 100 блогов zabivator18.01.2010 Одна из крайне неочевидных проблем кроется в способах взаимодействия программ, написанных на разных языках.
Все мои проблемы с json-rpc (за исключением кривых реализаций) кроются не в протоколе как таковом, не в постановке задачи (что мы хотим получить), а... в различиях языков.

Давайте рассмотрим незатейливый вызов

getObjectList( filter ) -> { ok, [ object1, object2, ... ] } | { error, Reason }

Записано в синтаксисе Erlang (для тех кто в теме про Ерланг проект - расслабтесь, с ним проблемы нету, проблемы в другом проекте. Ерланг просто удобная демонстрация).

Что делает эта функция?

Во-первых она принимает в качестве аргумента filter. Пусть этот filter описывает каким-то образом критерий выбора объектов из базы - например, условие поиска.
В качестве примера могу предложить вариант { [ "addDate", Date ] } - где Date - самая давняя дата поступления искомых объектов в базу. Таким образом, вызов просит найти все объекты в базе, поступившие после указанной даты.

Во-вторых, она возвращает результатом кортеж - либо ok (всё хорошо) и список объектов в результате, либо error - диагностирующую ошибку, а также её описание.

Давайте рассмотрим как работает с этой функцией клиент.
Если результатом является { ok, [ object1, object2 ] } - то всё хорошо, клиент получил ожидаемый ответ, и продолжает работу.
Если результатом является { error, Reason } - то нужно обработать ошибку. Например, показать пользователь диалог.

В данном примере уже видны проблемы. Функция getObjectList не имеет чётко зафиксированного результата. У неё на выходе альтернативы. Эти альтернативы имеют разную структуру - либо значение "ok" (допустим, это просто строка) и список объектов некоторого типа, либо значение "error" и строка с описанием ошибки.

В языках Ocaml, Erlang вернуть такую ошибку на клиенте достаточно просто - тип return value данной функции - Sum Types - либо/либо.
В языке Python данной проблемы вообще не стоит - клиент получает на выходе структуру, структуру которой он легко может исследовать динамически:
what, result = call( fitler )
if what == "ok":
    # result - список
    # обрабатываем список...
elif what = "error":
    # result - описание ошибки
else:
    # внутрення ошибка - неожиданный ответ сервера

Можно тоже самое завернуть в dict, можно придумать что-нибудь с getattr (по сути, тоже самое использование dict в неявной форме).

С Haskell всё тоже хорошо (Ocaml вариант). И с JavaScript (Python вариант). И с Lisp (продолжения не рассматриваем, т.к. они слишком специфичны для Lisp - High Order Function между языками по TCP/IP не погоняешь, ДА, КОНЕЧНО можно это сделать - но мне кажется это будет overkill).

А что делать с языками C/С++ и Java? В них нету Sum Types. Есть? Вам показалось.
Variant из Java/C# не имеет никакого отношения к Sum Types. Как и void* в С/C++.

Наиболее близкий аналог, что можно найти - это boost.variant в C++
union в Си, интерфейсы в Java / C# + паттерн посетитель (boost.variant - всего лишь посетитель на стероидах)... попробуйте описать описываемую выше функцию в C#/Java/C++/C, а потом приходител и поделитесь результатом. Как в Line of Codes, так и примерами, так и вашими субъективными ощущениями.

А всё почему?

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

C обычно нам предлагает Error Return Code, + GetLastErorr() (вернут код ошибки, дополнительные аргументы сложить в глобальную структура, доступаться к которой можно при помощи вызова GetLastError()).
setjmp/longjmp назвать удобным в использовании у меня язык не повернётся.

C++, Java, C# предлагают нам исключения.

Ocaml, Haskell - Sum Types + Pattern Matching. Ocaml также предлагает исключения.

Python, JavaScript уходят от решения проблемы благодаря динамической типизации - и пользователь может эмулировать Sum Types, может оформить функцию-обёртку, что разбирается с распространёнными типами ответов: "ok" или "error"? Если "ok" - отдать вызывающей функции, если "error" - предпринять действия (например, выбросить исключение) - таким изящным образом языки с динамической типизацией позволяют использовать любую стратегию обработки ошибок.
В Питоне такую обработку могут сильно облегчить декораторы.

Erlang предлагает на выбор либо pattern matching, либо exception (переход к исключениям как в Питоне).

Причесать разношёрстную компанию очень сложно. Представьте хотя бы проксирование исключений по rpc =)

Не так давно, уважаемый Мультиязычная разработка [info]plumqqz удивлялся в комментариях "зачем мне rpc транслятор?" - по сути транслятор из idl в обычный код.
Отвечаю, уважаемый крокодил - в случае динамически типизированных языков не нужен вообще.

В Python - к нему даже подходить не нужно. Интроспекция позволяет бесшовно встраиваться в пользовательский код (благодаря __call__, getatrr + **kwargs).
JavaScript - аналогично python.

С++? Java? C#? Не друг с другом, заметьте, а с другими языками или между собой.
Слова SOAP, DCOM, CORBA нифига не спасут - эти система интегрируются в языки далеко не естественным для них образом. Да и тащить CORBA, когда мне нужен light rpc... Из пушки по воробьям гуманней - они улететь могут. А CORBA придавит собой всё приложение )

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

Предыдущие записи блогера :
Архив записей в блогах:
Нарисованные котики от Антона Горцевича. Надеюсь Вам понравятся! ...
"Знаешь, как сильно, как ярко, как остро, Снега Казбека с небом слились, А видел ли ты, какой лазурью и охрой Выкрашен старый Тифлис?" В Москве невероятное количество мест где можно поесть. Но если хочешь поесть вкусно и недорого, то надо знать места. Совсем недавно я открыл для себя ...
Спикер Совета шуры Ирана Мохаммад Калибаф: "Иран разбил голову врага, развеял миф о так называемом «Железном куполе» и уничтожил жизненно важные объекты безопасности противника. Иранский народ защитил свои ядерные и ракетные достижения и продержался до последнего момента, не утратив ...
По повести Леонида Андреева «Иуда Искариот» режиссёр Андрей Богатырёв снял этот фильм. В роли Иуды - Алексей Шевченков (фильмография здесь: http://www.kino-teatr.ru/kino/acter/m/ros/4853/works/ ). Иуда, опытный вор, оказывается на базарной площади в тот момент, когда Христос читает ...
80 или даже 90% тех афганцев, которых я расспрашивал об отношении к русским говорили, что просто ненавидят . Я не знаю, кто придумал, что нас любят. В лицо, конечно, никто ничего не скажет. И если при первой встречи спросить в лоб: «Как ты относишься ...