Каков статус текущих реализаций функционального реактивного программирования?

Я пытаюсь визуализировать некоторые простые автоматические физические системы (такие как маятник, робот-оружие и т.д.) в Haskell. Часто эти системы могут быть описаны уравнениями, такими как

df/dt = c*f(t) + u(t)

где u(t) представляет собой своего рода "интеллектуальное управление". Эти системы очень хорошо подходят в парадигме функционального реактивного программирования.

Итак, я схватил книгу "Школа выражения Хаскеля" Пауля Худака, и обнаружил, что представленный там специфический для домена язык "FAL" (для языка функциональной анимации) действительно работает для моих простых игрушечных систем (хотя некоторые функции, особенно integrate), были слишком ленивы для эффективного использования, но легко фиксируется).

Мой вопрос: какая более зрелая, современная, ухоженная, настроенная на производительность альтернатива для более продвинутых или даже практических приложений сегодня?

Эта страница wiki содержит несколько опций для Haskell, но я не понимаю следующих аспектов:

  • Статус "реактивный", проект от Conal Eliott, который (как я понимаю), один из авторов этой парадигмы программирования, выглядит немного устаревшим. Мне нравится его код, но, может быть, мне стоит попробовать другие более современные альтернативы? Какое основное различие между ними, с точки зрения синтаксиса/производительности/стабильности выполнения?

  • Чтобы привести цитату из survey в разделе 6 раздела "... Реализации FRP все еще недостаточно эффективны или достаточно предсказуемы в производительности эффективно использоваться в доменах, требующих гарантий задержек...". В целом исследование предлагает некоторые интересные возможные оптимизации, учитывая тот факт, что FRP существует уже более 15 лет, создается впечатление, что эта проблема производительности может быть чем-то очень или даже неотъемлемо трудным для решения, по крайней мере, в течение нескольких лет. Это правда?

  • Тот же автор исследования говорит о "утечке времени" в своем blog. Является ли проблема уникальной для FRP или что-то, что мы обычно имеем при программировании на чистом, нестрогом языке? Вы когда-либо находили, что слишком сложно стабилизировать систему на основе FRP с течением времени, если она недостаточно эффективна?

  • Является ли это еще исследовательским проектом? Являются ли люди такими инженерами-инженерами, инженерами-роботологами, финансовыми инженерами и т.д., Фактически использующими их (на языке whaterver, который соответствует их потребностям)?

Хотя я лично предпочитаю реализацию Haskell, я открыт для других предложений. Например, было бы особенно интересно иметь реализацию Erlang - тогда было бы очень легко иметь интеллектуальный, адаптивный, самообучающийся серверный процесс!

Ответ 1

В настоящее время в основном существуют две практические библиотеки Haskell для функционального реактивного программирования. Оба поддерживаются отдельными лицами, но также получают кодовые вклады от других программистов Haskell:

  • Netwire фокусируется на эффективности, гибкости и предсказуемости. Он имеет свою собственную парадигму событий и может использоваться в тех областях, где традиционная FRP не работает, включая сетевые службы и сложные симуляции. Стиль: аппликативный и/или стрелковый. Первоначальный автор и сопровождающий: Ertugrul Söylemez (это я).

  • reactive-banana основывается на традиционной парадигме FRP. Хотя это практично использовать, он также служит основой для классических исследований FRP. Его основное внимание уделяется пользовательским интерфейсам, и есть готовый интерфейс к wx. Стиль: аппликативный. Первоначальный автор и сопровождающий: Генрих Апфельм.

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

Для игр, сетей, управления роботами и симуляций вы найдете Netwire полезным. Он поставляется с готовыми проводами для этих приложений, включая различные полезные дифференциалы, интегралы и множество функций для прозрачной обработки событий. Для руководства посетите документацию модуля Control.Wire на связанной странице.

Для графических пользовательских интерфейсов в настоящее время ваш лучший выбор - реактивно-банановый. У него уже есть wx-интерфейс (как отдельная библиотека reactive-banana-wx), а Heinrich много читает о FRP в этом контексте, включая образцы кода.

Чтобы ответить на другие ваши вопросы: FRP не подходит в сценариях, где вам нужна предсказуемость в режиме реального времени. Это во многом связано с Haskell, но, к сожалению, FRP трудно реализовать на языках более низкого уровня. Как только сам Haskell будет готов в режиме реального времени, FRP тоже туда попадет. Концептуально Netwire готова для приложений реального времени.

Утечки времени больше не являются проблемой, потому что они в значительной степени связаны с монадической структурой. Практические реализации FRP просто не предлагают монадического интерфейса. Ямба начала это, и Netwire и реактивно-банановые оба основывались на этом.

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

Ответ 2

Хотя уже есть хорошие ответы, я попытаюсь ответить на ваши конкретные вопросы.

  • реактивный не подходит для серьезных проектов из-за проблем с утечкой времени. (см. № 3). Текущая библиотека с наиболее похожим дизайном представляет собой реактивно-банановый, который был разработан с реактивной в качестве вдохновения и в обсуждении с Коналом Эллиотом.

  • Хотя сам Haskell не подходит для жестких приложений реального времени, в некоторых случаях можно использовать Haskell для приложений в реальном времени. Я не знаком с текущими исследованиями, но я не считаю, что это непреодолимая проблема. Я подозреваю, что любые системы, такие как Yampa, или системы генерации кода, такие как Atom, являются, пожалуй, лучшим подходом к решению этого вопроса.

  • "Время утечки" - это проблема, специфичная для переключаемой FRP. Утечка происходит, когда система не может освобождать старые объекты, потому что она может понадобиться, если в какой-то момент в будущем произойдет переход. В дополнение к утечке памяти (что может быть довольно серьезным), еще одним следствием является то, что при переключении система должна приостанавливаться, пока цепочка старых объектов проходит, чтобы генерировать текущее состояние.

Непереключаемые библиотеки frp, такие как Yampa и более старые версии реактивно-банановых, не страдают от утечек времени. Переменные библиотеки frp обычно используют одну из двух схем: либо у них есть специальная "монада создания", в которой создаются значения FRP, либо они используют параметр типа "старения", чтобы ограничить контексты, в которых могут возникать изменения. elerea (и, возможно, netwire?) используют первый, тогда как последние реакционно-банановые и грейпфруты используют последний.

Под "switchable frp" я имею в виду тот, который реализует функцию Conal switcher :: Behavior a -> Event (Behavior a) -> Behavior a или идентичную семантику. Это означает, что форма сети может динамически переключаться по мере ее запуска.

Это на самом деле не противоречит утверждению @ertes о монадических интерфейсах: оказывается, что предоставление экземпляра Monad для Event делает возможными утечки времени, и с любым из указанных выше подходов уже невозможно определить эквивалентные экземпляры Monad.

Наконец, хотя еще предстоит еще много работы с FRP, я думаю, что некоторые из новых платформ (реактивный банан, elerea, netwire) стабильны и достаточно зрелы, чтобы вы могли создавать над ними надежный код. Но вам, возможно, придется потратить много времени на изучение входов и выходов, чтобы понять, как добиться хорошей производительности.

Ответ 3

Я собираюсь перечислить несколько элементов в пространстве Моно и .Net и один из пространства Haskell, который я нашел не так давно. Я начну с Haskell.

Elm - ссылка

Его описание в соответствии с его сайтом:

Elm стремится сделать более приятным внешний вид веб-разработки. Это вводит новый подход к программированию GUI, который корректирует системные проблемы HTML, CSS и JavaScript. Elm позволяет вам быстро и легко работать с визуальной компоновкой, использовать холст, управлять сложный пользовательский ввод и выход из аддона обратного вызова.

У него есть собственный вариант FRP. От игры с ее примерами она кажется довольно зрелой.

Реактивные расширения - ссылка

Описание на первой странице:

Reactive Extensions (Rx) - это библиотека для составления асинхронных и основанные на событиях программы с использованием наблюдаемых последовательностей и LINQ-стиля операторы запроса. Используя Rx, разработчики представляют асинхронные данные потоки с Observables, запрос асинхронных потоков данных с использованием LINQ операторов и параметризовать concurrency в асинхронных данных потоков с использованием планировщиков. Проще говоря, Rx = Observables + LINQ + Планировщики.

Реактивные расширения поступают от MSFT и реализуют множество превосходных операторов, которые упрощают обработку событий. Это был открытый источник всего пару дней назад. Он очень зрелый и используется в производстве; на мой взгляд, это был бы более удобный API для API Windows 8, чем предоставляет TPL-библиотека; потому что наблюдаемые могут быть как горячими, так и холодными, повторенными/объединенными и т.д., тогда как задачи всегда представляют собой горячие или выполненные вычисления, которые либо запущены, либо повреждены, либо завершены.

Я написал серверный код, используя Rx для асинхронности, но я должен признать, что писать функционально на С# может быть немного раздражающим. F # имеет пару оболочек, но было сложно отслеживать разработку API, потому что группа относительно закрыта и не поддерживается MSFT, как и другие проекты.

Его открытый источник пришел с открытым источником его IL-to-JS-компилятора, поэтому он, вероятно, мог бы хорошо работать с JavaScript или Elm.

Вы могли бы связать F #/С#/JS/Haskell вместе очень хорошо, используя брокер сообщений, например RabbitMQ и SocksJS.

Инструментарий UI для Bling - ссылка

Описание на первой странице:

Bling - это библиотека на основе С# для простого программирования изображений, анимаций, взаимодействия и визуализации в Microsoft WPF/.NET. Bling - ориентированных на техников-конструкторов, т.е. дизайнеров, которые иногда чтобы помочь в быстром прототипировании богатых идей дизайна пользовательского интерфейса. Студенты, художники, исследователи и любители также найдут Bling полезно как инструмент для быстрого выражения идей или визуализации. API и конструкции Bling API оптимизированы для быстрого программирования выбросить код в противоположность тщательному программированию производства код.

Бесплатная статья LtU.

Я тестировал это, но не работал с ним для проекта клиента. Это выглядит потрясающе, имеет приятную перегрузку оператора С#, которая формирует привязки между значениями. Он использует свойства зависимостей в WPF/SL/(WinRT) в качестве источников событий. Его 3D-анимация хорошо работает на разумном оборудовании. Я бы использовал это, если бы я оказался в проекте, нуждающемся в визуализации; вероятно, перенося его на Windows 8.

ReactiveUI - ссылка

Пол Беттс, ранее в MSFT, теперь в Github, написал эту структуру. Я работал с ним довольно широко и как модель. Он более развязан, чем Blink (по своей природе от использования Rx и его абстракций), что упрощает использование unit test кода. В нем написано клиент github git для Windows.

Комментарии

Реактивная модель достаточно эффективна для большинства приложений, требующих высокой производительности. Если вы думаете о жестком режиме реального времени, я бы сказал, что большинство GC-языков имеют проблемы. Rx, ReactiveUI создает некоторое количество небольших объектов, которые должны быть GCed, потому что то, как создаются/удаляются подписи, и промежуточные значения продвигаются в реактивной "монаде" обратных вызовов. В общем, на .Net я предпочитаю реактивное программирование над программированием на основе задач, потому что обратные вызовы являются статическими (известны во время компиляции, без распределения), в то время как задачи динамически распределяются (неизвестно, для всех вызовов нужен экземпляр, созданный мусор) - и lambdas компилируется в генерируемые компилятором.

Очевидно, что С# и F # строго оцениваются, поэтому утечка времени здесь не проблема. То же самое для JS. Это может быть проблема с воспроизводимыми или кэшированными наблюдаемыми, хотя.