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


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

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

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

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

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

этой странице перечислены несколько вариантов Хаскелл, но я не совсем понимаю в следующих отношениях:

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

  2. цитата из обследования in 2011, Раздел 6, "... Реализации FRP по-прежнему недостаточно эффективны или достаточно предсказуемы по производительности, чтобы эффективно использоваться в доменах, требующих гарантий задержки ...". Хотя опрос предлагает некоторые интересные возможные оптимизации, учитывая тот факт, что FRP существует более 15 лет, у меня создается впечатление, что эта проблема производительности может быть чем-то очень или даже по сути трудно решить, по крайней мере, в течение нескольких лет. Заключаться в следующем правда?

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

  4. Это все еще исследовательский проект? Люди любят инженеры завода, инженеры робототехники, финансовые инженеры и т. д. на самом деле, используя их (на каком языке сервера, который соответствует их потребностям)?

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

3 85

3 ответа:

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

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

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

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

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

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

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

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

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

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

  1. реактивное не годно к употреблению для серьезных проектов, должных к проблемам утечки времени. (см. #3). Нынешняя библиотека с наиболее похожим дизайном является reactive-banana, которая была разработана с помощью reactive в качестве вдохновения и в обсуждении с Коналом Эллиотом.

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

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

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

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

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

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

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

Вязовая - ссылке

его описание согласно его сайту:

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

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

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

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

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

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

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

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

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

Bling UI Toolkit -ссылке

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

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

бесплатный LtU-article.

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

ReactiveUI -ссылке

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

комментарии

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

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