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


90

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

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

де u(t)являє собою якийсь "інтелектуальний контроль". Ці системи, схоже, дуже добре вписуються в парадигму функціонального реактивного програмування.

Так що я схопив книгу «Haskell школа вираження» Пол Hudák, і виявив , що домен конкретного мови «FAL» (для функціонального Animation мови) представлені там на самому ділі працює досить pleasently для моїх простих іграшок систем (хоча деякі функції, в зокрема integrate, здавалося, занадто лінивий для ефективного використання, але легко виправити).

Моє запитання полягає в тому, що є сьогодні більш дозрілою, сучасною, доглянутою та налаштованою на ефективність альтернативою для більш просунутих чи навіть практичних програм сьогодні?

На цій вікі-сторінці перелічено декілька варіантів Haskell, але мені незрозумілі наступні аспекти:

  1. Статус "реактивного", проект Коналя Еліотта, який (як я розумію) є одним із винахідників цієї парадигми програмування, виглядає дещо застарілим. Мені подобається його код, але, можливо, мені слід спробувати інші більш сучасні альтернативи? Яка основна різниця між ними, з точки зору синтаксису / продуктивності / стабільності виконання?

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

  3. Той самий автор опитування розповідає про "витоки часу" у своєму блозі . Проблема є унікальною для FRP чи чогось у нас, як правило, при програмуванні на чистій, несуворій мові? Вам коли-небудь було занадто складно стабілізувати систему на основі FRP з часом, якщо вона недостатньо ефективна?

  4. Це все ще проект наукового рівня? Чи люди, такі як інженери заводів, інженери робототехніки, фінансові інженери тощо, насправді ними користуються (іншою мовою, яка відповідає їхнім потребам)?

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

Відповіді:


82

Зараз є в основному дві практичні бібліотеки Haskell для функціонального реактивного програмування. Обидва вони підтримуються одинокими людьми, але отримують внески коду і від інших програмістів Haskell:

  • Netwire фокусується на ефективності, гнучкості та передбачуваності. Він має власну парадигму подій і може використовуватися в областях, де традиційний FRP не працює, включаючи мережеві послуги та складні симуляції. Стиль: прикладний та / або стрілковий. Первинний автор та супровідник: Ертугрул Сойлемез (це я).

  • реактивний банан ґрунтується на традиційній парадигмі FRP. Хоча практичне використання, воно також служить підставою для класичних досліджень FRP. Його основна увага приділяється користувальницьким інтерфейсам, і є готовий інтерфейс для wx. Стиль: аплікативний. Початковий автор та супровідник: Генріх Апфельмус.

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

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

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

Щоб відповісти на інші ваші запитання: FRP не підходить у тих випадках, коли вам потрібна передбачуваність у реальному часі. Це багато в чому пов’язано з Хаскеллом, але, на жаль, FRP важко реалізувати мовами нижчого рівня. Як тільки сам Хаскелл стане готовим до реального часу, FRP також потрапить туди. Концептуально Netwire готовий до роботи в режимі реального часу.

Витоки часу насправді вже не є проблемою, оскільки вони значною мірою пов'язані з монадичними рамками. Практичні реалізації FRP просто не пропонують монадичний інтерфейс. Ямпа розпочав це, і Netwire та реактивний банан базуються на цьому.

На даний момент я не знаю жодного комерційного чи масштабного проекту, який би використовував FRP. Бібліотеки готові, але я думаю, що люди - ні.


Чудова відповідь, спасибі .. буде веселою вправою впровадити деякі алгоритми посилення навчання у верхній частині вашої бібліотеки.
мніш

3
Примітно, що нещодавня інді-гра, написана на Haskell ( Nikki and the Robots ), прийняла рішення не використовувати FRP.
Alex R

23

Хоча вже є кілька хороших відповідей, я спробую відповісти на ваші конкретні запитання.

  1. реактивний не придатний для серйозних проектів через проблеми з витоками часу. (див. No3). Нинішня бібліотека з найбільш подібним дизайном - реактив-банан, яка була розроблена з реактивом як натхнення та в обговоренні з Кональ Елліот.

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

  3. "Витік часу" - це проблема, що стосується перемикання FRP. Витік відбувається, коли система не може звільнити старі об'єкти, оскільки вони можуть їм знадобитися, якщо в майбутньому відбудеться перемикання. На додаток до витоку пам'яті (що може бути досить серйозним), ще одним наслідком є ​​те, що, коли відбувається перемикання, система повинна зробити паузу під час проходження ланцюга старих об'єктів для формування поточного стану.

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

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

Це насправді не суперечить твердженню @ ertes про монадичні інтерфейси: виявляється, що надання Monadекземпляра для екземпляра Eventробить можливим витік часу, і з будь-яким із наведених підходів вже неможливо визначити еквівалентні екземпляри Monad.

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


2
Щодо бібліотек на основі стрілок (Yampa, netwire), їх також можна переключати. Причина полягає в тому, що стрілки мають вбудоване старіння, і насправді від нього не можна позбутися. (Будучи потоковими трансформаторами, стрілки агностикують час початку свого вхідного потоку.)
Генріх Апфельмус


1
@HeinrichApfelmus: це цікавий момент. Я взагалі не думаю, що бібліотеки, засновані на стрілках, можна переключати так само, як елерея / грейпфрут / поточно реактивний банан. Я думаю, що їх перемикання набагато ближче до того, що вимагалося в попередніх версіях реактивного банана. Однак це просто кишкове відчуття, я не замислювався над цим, щоб навіть описати, що я маю на увазі.
Джон Л

2
@DanBurton дякую, я безуспішно намагався запам'ятати це ім'я. Я згоден з тим, що натрій слід вважати сучасною бібліотекою FRP, хоча він не такий популярний, як реактивний банан.
Джон Л

Незважаючи на те, що дискусію, що триває, трохи важко відстежити, схоже, це вказує на те, що система "м'якого" реального часу дійсно можлива, за умови, що час GC може певним чином обмежуватися. У будь-якому разі дякую за вашу чудову відповідь.
мніш

20

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

В'яз - посилання

Його опис згідно з його сайтом:

Elm прагне зробити інтерфейсну веб-розробку більш приємною. Він вводить новий підхід до програмування графічного інтерфейсу, який виправляє системні проблеми HTML, CSS та JavaScript. Elm дозволяє швидко та легко працювати з візуальним макетом, користуватися полотном, керувати складним введенням користувача та рятуватися від пекла зворотного виклику.

У нього є свій варіант FRP . З гри з його прикладами це здається досить зрілим.

Реактивні розширення - посилання

Опис із першої сторінки:

Reactive Extensions (Rx) - це бібліотека для складання асинхронних програм та програм на основі подій із використанням спостережуваних послідовностей та операторів запитів у стилі LINQ. Використовуючи Rx, розробники представляють асинхронні потоки даних за допомогою Observables, запитують асинхронні потоки даних за допомогою операторів LINQ та параметризують паралельність в асинхронних потоках даних за допомогою планувальників. Простіше кажучи, Rx = спостережувані + LINQ + планувальники.

Reactive Extensions походить від 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 .

Я перевірив це, але не працював із ним для клієнтського проекту. Це виглядає чудово, має приємне перевантаження оператора C #, яке утворює прив'язки між значеннями. Він використовує властивості залежностей у WPF / SL / (WinRT) як джерела подій. Його 3D-анімація добре працює на розумному обладнанні. Я б скористався цим, якщо опинюся у проекті, який потребує візуалізації; ймовірно, переносячи його на Windows 8.

ReactiveUI - посилання

Пол Беттс, раніше в MSFT, а тепер у Github, написав цю структуру. Я працював із цим досить широко і подобається модель. Він більш відокремлений від Blink (за своєю природою від використання Rx та його абстракцій) - полегшує модульне тестування коду за його допомогою. У цьому написано github git-клієнт для Windows.

Коментарі

Реактивна модель є достатньо ефективною для найбільш вимогливих до продуктивності програм. Якщо ви думаєте про жорсткий реальний час, я б поклався на пари, що більшість GC-мов мають проблеми. Rx, ReactiveUI створює деяку кількість малого об'єкта, який потрібно обробити GCed, оскільки саме так створюються / розподіляються підписки та прогресуються проміжні значення в реактивній "монаді" зворотних викликів. Загалом у .Net я віддаю перевагу реактивному програмуванню перед програмуванням на основі завдань, тому що зворотні виклики є статичними (відомі під час компіляції, без розподілу), тоді як завдання динамічно розподіляються (невідомо, всі виклики потребують екземпляру, створене сміття) - і лямбди компілюються в класи, створені компілятором.

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


Дякую за чудову відповідь. Одне з речей, яке мені сподобалось для реалізацій Haskell FRP, це те, що вони, здається, дозволяють мені чітко роз'єднати обчислення для управління u(t)та моделювання для f(t). Це стосується реалізацій F #?
мніш

Думаю, ви можете сказати, що ці дві функції тимчасово роз'єднані, так. Вони, ймовірно, не логічно роз'єднані. ;)
Генрік

Наскільки мені відомо, Reactive Extensions та інші більш відшліфовані інтерфейси, орієнтовані на користувальницький інтерфейс (і насправді все за межами Haskell), використовують лише парні семантики - це означає, що вони мають поняття подій, які можна ввімкнути, але не поняття безперервних часових сигналів, які можуть взаємодіяти рівноправно. Думаю, для створення гізів це добре. Однак для побудови симуляцій та моделей це може бути прикро.
sclv

Ви маєте на увазі, що всі реалізації функціонального реактивного програмування lib повинні моделювати час постійно, а не дискретно? Я знайшов статтю під назвою "Процесна алгебра із синхронізацією: реальний час та дискретний час" - це хороша відправна точка для розуміння того, про що ви говорите?
Генрік

Я не кажу, що всім потрібно - хтось робить, хтось ні. Але ті, хто робить, більше підходять для певних завдань, а ті, хто більше, не підходять для інших ...
sclv
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.