Или рассказ о трех попытках внедрения новых языков программирования на рабочем месте и их эффектах перекрестного опыления.

Меня всегда привлекали языки программирования, особенно функциональные. Это восходит к 1990 году, когда я изучил Miranda (предшественник Haskell) на курсе программирования в Университете Монреаля. Затем я изучил Схему, когда работал над докторской диссертацией. и был поражен его простотой, понятным дизайном. Ужасные круглые скобки (Scheme является членом семейства языков Lisp, хорошо известного своим использованием в старой системе искусственного интеллекта, но также и тем, что содержат круглые скобки) никогда не были для меня проблемой. После определенного момента вы их больше не видите. На самом деле, они мне всегда нравились, а хорошо написанные программы на Scheme могут действительно эстетично смотреться. Я все еще верю в это. Но в то время я думал, что синтаксис не так важен для принятия языка программирования.

Перенесемся на несколько лет вперед и пару детей ...

До работы в Nu Echo я несколько месяцев проработал в двух компаниях, занимаясь профессиональным программированием на Scheme / Lisp. Первым была разработка технологии трехмерного твердотельного моделирования с использованием языка сценариев Scheme. У второго была действительно сложная среда разработки Lisp. Не лучшая реализация IMO, но IDE была просто… Вау! Программировать было так приятно! Это было откровением!

Затем в 2003 году я присоединился к Nu Echo, компании, работающей один год, по разработке приложений распознавания речи для центров обработки вызовов в крупных организациях. Да, крупные организации ... В то время это означало Java! (И, по сути, до сих пор.) Я, конечно, знал Java. Это не был мой любимый язык, но, по крайней мере, Eclipse IDE немного облегчила его многословие. Я не могу представить себе серьезное программирование на Java без достойной IDE, такой как Eclipse или IntelliJ IDEA.

Схема и ужасные скобки

Итак, я здесь занимаюсь программированием на Java. Но вы не можете так легко отнять у кого-то функциональное / схемное программирование! И я выпил Paul Graham Kool-Aid… Вы легко можете догадаться, что было дальше!

Я очень старался убедить других (включая руководство), что Scheme подойдет компании. Я по желанию обсуждал достоинства языка, сделал несколько прототипов DSL в Kawa Scheme, системе Scheme, которая компилируется в байт-код JVM и довольно хорошо интегрируется с библиотеками Java.

Но все оказалось немного сложнее, чем я предполагал вначале. Сам по себе язык - ничто. Вам нужна хорошая поддержка редактора (Emacs просто не вариант), линтеры, фреймворки для модульного тестирования и тому подобное. Поскольку Eclipse была де-факто IDE Nu Echo, я решил разработать плагин Scheme (SchemeScript), чтобы хотя бы эта часть была правильной.

Затем, имея некоторый опыт написания плагинов Eclipse, я начал разработку полной IDE для грамматик распознавания речи ABNF для приложений VoiceXML, названной NuGram IDE.

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

Однако сам язык так и не получил особой поддержки внутри компании, что привело к концентрации опыта и ноу-хау в руках всего лишь нескольких человек (что никогда не бывает хорошо!). Чужой синтаксис Scheme, безусловно, в значительной степени ответственен за это.

Но самым удивительным и длительным влиянием Scheme на компанию стали в большей степени выявленные концепции. У меня было бесчисленное количество обсуждений с Жаном-Филиппом Гариепи об использовании продолжений, и особенно о веб-серверах на основе продолжений (концепция, изобретенная исследователем Кристианом Кейннеком еще в 2000 году), где веб-приложения написаны в более последовательной форме, скрывая большая часть обмена между клиентом и сервером. Оказывается, эта концепция вдохновила нашу облегченную структуру Rivr для разработки приложений на основе VoiceXML. Он не полагается на полные продолжения (это все еще Java!), Но предоставляет аналогичный интерфейс. Один пишет диалог как последовательную программу, например:

Для этого вам нужно 2 потока, один для приложения, а другой для части, которая получает запросы от клиента и отправляет ему ответы.

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

Иногда идеи исходят из самих программных концепций!

Вторая попытка: Erlang

В 2009 году мы начали работу над размещенной службой для надежного синтаксического анализа и семантической интерпретации текстовых входных данных. Вы можете думать об этом как о предшественнике движков НЛП для чат-ботов, но без части машинного обучения. Мы подумали, что этот проект станет идеальным кандидатом для экспериментов с языком программирования Erlang и OTP (Open Telecom Platform). Этот язык был разработан Эрикссон в конце 80-х годов для создания более масштабируемых и надежных телекоммуникационных приложений. Отличительной особенностью этого языка является то, что он в значительной степени полагается на низкоуровневые, очень дешевые потоки, называемые процессами, которые общаются посредством передачи сообщений. Каждый процесс запрограммирован в функциональном стиле.

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

А внутри компании, хотя все больше людей интересовалось тем, как мы используем Erlang, я все же думаю, что синтаксис (который очень похож на Prolog) был проблемой. А также отсутствие хорошего редактора.

Но мы снова почувствовали влияние Erlang непредсказуемым образом. Несколько лет спустя Nu Echo выиграла проект по созданию сложного кластерного решения для крупного банка в Канаде. Он состоял из веб-консоли конфигурации и среды выполнения, в которой выполнялись сценарии, разработанные с помощью консоли. Поскольку это должна была быть полностью избыточная среда, всю конфигурацию пришлось реплицировать на все узлы в кластере.

Система была разработана с использованием некоторых принципов и архитектуры, унаследованных от Erlang. Все элементы конфигурации были организованы в древовидную структуру. Каждое изменение конфигурации было применено к дереву функционально, то есть дерево реплицируется, за исключением одного узла, который содержал изменение. (Фактически, поскольку оба дерева почти идентичны, за исключением одного узла, большинство узлов являются общими вместо двух отдельных копий.) Когда все проверки выполнены в новом дереве, может произойти простая замена указателей, приложение теперь используя только что созданное дерево. Это действительно похоже на то, как вы бы структурировали такую ​​систему в Erlang: у вас есть процесс, который получает сообщение, функционально изменяет его состояние, а затем ожидает следующего сообщения.

Эта идея была действительно очень простой. Но это имело большое значение с точки зрения упрощения конструкции и обеспечения надежности. Если во время создания второго дерева возникает проблема (ошибка, больше нет памяти и т. Д.), Возникает исключение, и предыдущая версия остается в силе. Никаких повреждений структур данных! Фактически, если исключить некоторые проблемы репликации данных, которые у нас были в производственной среде из-за кластерного разделения мозгов, у нас не было ни одной ошибки в этой части системы за 6 лет. Это о многом говорит!

А потом Эликсир!

Мне всегда нравился Эрланг. На самом деле мне сейчас больше нравится Erlang, чем Scheme. Причина проста. Вам нужно больше, чем просто язык, вам нужна платформа. Например, Java и JVM, а также инструменты, которые поставляются с ними. С Erlang у вас есть хороший язык, но, что более важно, платформа для начала разработки распределенных приложений с высокой степенью параллелизма. И у вас есть все инструменты для мониторинга ваших программ во время выполнения (приложение Observer позволяет вам контролировать любой узел в кластере, проверять внутренние таблицы, исследовать ваши службы и т. Д.).

А потом появился Эликсир. Язык, разработанный людьми из сообщества Ruby / Rails, с упором на простой, но привлекательный синтаксис и инструменты.

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

Другой аспект языка, который был очень привлекательным для систем, которые мы строим, - это сопоставление с образцом. Большая часть кода, который мы пишем, предназначен для взаимодействия с существующими API на основе HTTP, обычно использующими и производящими структуры JSON. Использование Elixir, Phoenix и некоторых других библиотек, выполнение HTTP-запросов, анализ JSON и деструктуризация документов для извлечения контента - это совсем несложно. Просто попробуйте это на Java!

Я думаю, что Elixir привлек внимание большего количества людей внутри компании, чем Scheme и Erlang. Мы смогли нанять стажеров на основе нашего выбора языка, и всем, кто пробовал язык, он просто нравится! Инструменты отличные, постоянно улучшаются, и поддержка редакторов тоже (по крайней мере, в Atom, Sublime, VSCode). Наш CI-сервер поддерживает это. Чего еще нам ожидать?

В конце концов, синтаксис имеет значение!

Я думаю, здесь можно сделать двоякий вывод:

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

Всегда будьте внимательны, чтобы узнать что-то новое! Никогда не знаешь!