Apa status implementasi Pemrograman Reaktif Fungsional saat ini?

90

Saya mencoba untuk memvisualisasikan beberapa sistem fisik otomatis sederhana (seperti pendulum, lengan robot, dll.) Di Haskell. Seringkali sistem tersebut dapat dijelaskan dengan persamaan seperti

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

di mana u(t)mewakili semacam 'kontrol cerdas'. Sistem tersebut terlihat sangat cocok dengan paradigma Pemrograman Reaktif Fungsional.

Jadi saya mengambil buku "Sekolah Ekspresi Haskell" oleh Paul Hudak, dan menemukan bahwa bahasa khusus domain "FAL" (untuk Bahasa Animasi Fungsional) yang disajikan di sana sebenarnya bekerja cukup menyenangkan untuk sistem mainan sederhana saya (meskipun beberapa fungsi, terutama integrate, sepertinya terlalu malas untuk penggunaan yang efisien, tetapi mudah diperbaiki).

Pertanyaan saya adalah, apa alternatif yang lebih matang, terkini, terpelihara dengan baik, kinerja yang disesuaikan untuk aplikasi yang lebih maju, atau bahkan praktis saat ini?

Halaman wiki ini mencantumkan beberapa opsi untuk Haskell, tetapi saya tidak jelas tentang hal-hal berikut:

  1. Status “reactive”, proyek dari Conal Eliott yang (seperti yang saya pahami) salah satu penemu paradigma pemrograman ini, terlihat agak basi. Saya suka kodenya, tetapi mungkin saya harus mencoba alternatif lain yang lebih mutakhir? Apa perbedaan utama di antara mereka, dalam hal sintaks / kinerja / stabilitas runtime?

  2. Mengutip dari survei tahun 2011, Bagian 6, " ... Implementasi FRP masih belum cukup efisien atau kinerjanya cukup dapat diprediksi untuk digunakan secara efektif di domain yang memerlukan jaminan latensi ... ". Meskipun survei menunjukkan beberapa kemungkinan pengoptimalan yang menarik, mengingat fakta bahwa FRP telah ada selama lebih dari 15 tahun, saya mendapat kesan bahwa masalah kinerja ini mungkin sesuatu yang sangat atau bahkan secara inheren sulit dipecahkan setidaknya dalam beberapa tahun. Apakah ini benar?

  3. Penulis survei yang sama berbicara tentang "kebocoran waktu" di blognya . Apakah masalahnya unik pada FRP, atau sesuatu yang biasanya kita alami saat membuat program dalam bahasa yang murni dan tidak ketat? Pernahkah Anda merasa terlalu sulit untuk menstabilkan sistem berbasis FRP dari waktu ke waktu, jika kinerjanya tidak cukup?

  4. Apakah ini masih proyek tingkat penelitian? Apakah orang-orang seperti insinyur pabrik, insinyur robotika, insinyur keuangan, dll. Benar-benar menggunakannya (dalam bahasa apa pun yang sesuai dengan kebutuhan mereka)?

Meskipun saya pribadi lebih suka penerapan Haskell, saya terbuka untuk saran lain. Misalnya, akan sangat menyenangkan untuk memiliki implementasi Erlang --- maka akan sangat mudah untuk memiliki proses server yang cerdas, adaptif, dan belajar mandiri!

mnish
sumber

Jawaban:

82

Saat ini terdapat dua pustaka Haskell praktis yang tersedia untuk pemrograman reaktif fungsional. Keduanya dikelola oleh satu orang, tetapi menerima kontribusi kode dari pemrogram Haskell lain juga:

  • Netwire berfokus pada efisiensi, fleksibilitas, dan prediktabilitas. Ini memiliki paradigma kejadiannya sendiri dan dapat digunakan di area di mana FRP tradisional tidak berfungsi, termasuk layanan jaringan dan simulasi kompleks. Gaya: aplikatif dan / atau panah. Penulis dan pengelola awal: Ertugrul Söylemez (ini saya).

  • reaktif-pisang dibangun di atas paradigma FRP tradisional. Meskipun praktis untuk digunakan, ini juga berfungsi sebagai dasar untuk penelitian FRP klasik. Fokus utamanya adalah pada antarmuka pengguna dan ada antarmuka yang siap pakai untuk wx. Gaya: aplikatif. Penulis dan pengelola awal: Heinrich Apfelmus.

Anda harus mencoba keduanya, tetapi tergantung pada aplikasi Anda, kemungkinan besar Anda akan menemukan satu atau yang lain yang lebih cocok.

Untuk game, jaringan, kontrol robot, dan simulasi, Anda akan merasakan manfaat Netwire. Muncul dengan kabel siap pakai untuk aplikasi tersebut, termasuk berbagai perbedaan yang berguna, integral, dan banyak fungsi untuk penanganan acara yang transparan. Untuk tutorial, kunjungi dokumentasi Control.Wiremodul di halaman yang saya tautkan.

Untuk antarmuka pengguna grafis saat ini, pilihan terbaik Anda adalah reaktif-banana. Ia sudah memiliki antarmuka wx (sebagai perpustakaan terpisah reaktif-banana-wx) dan Heinrich banyak blog tentang FRP dalam konteks ini termasuk contoh kode.

Untuk menjawab pertanyaan Anda yang lain: FRP tidak cocok dalam skenario di mana Anda membutuhkan prediktabilitas waktu nyata. Hal ini sebagian besar disebabkan oleh Haskell, tetapi sayangnya FRP sulit untuk diwujudkan dalam bahasa tingkat rendah. Segera setelah Haskell siap secara real-time, FRP juga akan melakukannya. Secara konseptual Netwire siap untuk aplikasi real-time.

Kebocoran waktu tidak lagi menjadi masalah, karena sebagian besar terkait dengan kerangka monadik. Implementasi FRP praktis tidak menawarkan antarmuka monadik. Yampa telah memulai ini dan Netwire serta reactive-banana keduanya membangunnya.

Saya tahu tidak ada proyek komersial atau berskala besar yang menggunakan FRP sekarang. Perpustakaannya sudah siap, tetapi saya pikir orang-orangnya belum - belum.

ertes
sumber
Jawaban yang bagus, terima kasih .. ini akan menjadi latihan yang menyenangkan untuk menerapkan beberapa algoritma pembelajaran penguatan di atas perpustakaan Anda.
mnish
3
Khususnya, game indie baru-baru ini yang ditulis di Haskell ( Nikki and the Robots ) membuat keputusan untuk tidak menggunakan FRP.
Alex R
23

Meskipun sudah ada beberapa jawaban yang bagus, saya akan mencoba menjawab pertanyaan spesifik Anda.

  1. reaktif tidak dapat digunakan untuk proyek serius, karena masalah kebocoran waktu. (lihat # 3). Perpustakaan saat ini dengan desain yang paling mirip adalah pisang reaktif, yang dikembangkan dengan reaktif sebagai inspirasi, dan berdiskusi dengan Conal Elliott.

  2. Meskipun Haskell sendiri tidak sesuai untuk aplikasi hard real-time, Haskell dapat digunakan untuk aplikasi soft realtime dalam beberapa kasus. Saya tidak terbiasa dengan penelitian saat ini, tetapi saya tidak yakin ini adalah masalah yang tidak dapat diatasi. Saya menduga bahwa sistem seperti Yampa, atau sistem pembuatan kode seperti Atom, mungkin merupakan pendekatan terbaik untuk menyelesaikan masalah ini.

  3. Sebuah "kebocoran waktu" adalah masalah khusus untuk FRP yang dapat dialihkan. Kebocoran terjadi ketika sistem tidak dapat membebaskan objek lama karena mungkin memerlukannya jika sakelar akan terjadi di masa mendatang. Selain kebocoran memori (yang bisa sangat parah), konsekuensi lainnya adalah, saat sakelar terjadi, sistem harus berhenti sementara rantai objek lama dilintasi untuk menghasilkan status saat ini.

Library FRP yang tidak dapat dialihkan seperti Yampa dan versi reaktif-banana yang lebih lama tidak mengalami kebocoran waktu. Library frp yang dapat dialihkan umumnya menggunakan salah satu dari dua skema: apakah mereka memiliki "monad penciptaan" khusus di mana nilai FRP dibuat, atau mereka menggunakan parameter jenis "penuaan" untuk membatasi konteks di mana sakelar dapat terjadi. elerea (dan mungkin netwire?) menggunakan yang pertama, sedangkan pisang reaktif dan grapefruit baru-baru ini menggunakan yang terakhir.

Yang saya maksud dengan "switchable frp" adalah yang mengimplementasikan fungsi Conal switcher :: Behavior a -> Event (Behavior a) -> Behavior a, atau semantik identik. Artinya, bentuk jaringan dapat beralih secara dinamis saat dijalankan.

Ini tidak benar-benar bertentangan dengan pernyataan @ ertes tentang antarmuka monad: ternyata menyediakan Monadcontoh untukEvent membuat kebocoran waktu menjadi mungkin, dan dengan salah satu pendekatan di atas, tidak mungkin lagi untuk mendefinisikan instance Monad yang setara.

Akhirnya, meskipun masih banyak pekerjaan yang harus diselesaikan dengan FRP, saya pikir beberapa platform yang lebih baru (reaktif-banana, elerea, netwire) sudah cukup stabil dan matang sehingga Anda dapat membuat kode yang andal dari mereka. Tetapi Anda mungkin perlu menghabiskan banyak waktu mempelajari seluk beluk untuk memahami bagaimana mendapatkan kinerja yang baik.

John L.
sumber
2
Mengenai perpustakaan berbasis panah (Yampa, netwire), mereka juga dapat dialihkan. Alasannya adalah karena panah memiliki penuaan bawaan, Anda tidak dapat benar-benar menghilangkannya. (Menjadi transformator aliran, anak panah menjadi agnostik tentang waktu mulai aliran input mereka.)
Heinrich Apfelmus
3
Jangan lupa musuh pisang reaktif : natrium .
Dan Burton
1
@HeinrichApfelmus: itu poin yang menarik. Saya biasanya tidak menganggap perpustakaan berbasis panah dapat dialihkan dengan cara yang sama seperti elerea / grapefruit / current-reactive-banana. Saya pikir peralihan mereka jauh lebih dekat dengan apa yang dibutuhkan dalam versi reaktif-banana sebelumnya. Ini hanya firasat, saya belum cukup memikirkannya untuk menggambarkan apa yang saya maksud.
John L
2
@DanBurton terima kasih, saya mencoba tidak berhasil mengingat nama itu. Saya setuju bahwa natrium harus dianggap sebagai pustaka FRP modern, meskipun tidak sepopuler pisang reaktif.
John L
Meskipun diskusi yang berlangsung agak sulit untuk diikuti, tampaknya menunjukkan bahwa sistem soft-realtime memang mungkin, asalkan waktu GC dapat dibatasi. Pokoknya terima kasih atas jawaban Anda yang luar biasa.
mnish
20

Saya akan membuat daftar beberapa item di ruang Mono dan .Net dan satu dari ruang Haskell yang saya temukan belum lama ini. Saya akan mulai dengan Haskell.

Elm - link

Deskripsi sesuai situsnya:

Elm bertujuan untuk membuat pengembangan web front-end lebih menyenangkan. Ini memperkenalkan pendekatan baru untuk pemrograman GUI yang memperbaiki masalah sistemik HTML, CSS, dan JavaScript. Elm memungkinkan Anda untuk bekerja dengan cepat dan mudah dengan tata letak visual, menggunakan kanvas, mengelola masukan pengguna yang rumit, dan keluar dari neraka panggilan balik.

Ini memiliki varian FRP sendiri . Dari bermain-main dengan contoh-contohnya, tampaknya cukup dewasa.

Ekstensi Reaktif - tautan

Deskripsi dari halaman depannya:

Ekstensi Reaktif (Rx) adalah pustaka untuk menyusun program asinkron dan berbasis peristiwa menggunakan urutan yang dapat diamati dan operator kueri gaya LINQ. Menggunakan Rx, pengembang merepresentasikan aliran data asinkron dengan Observable, membuat kueri aliran data asinkron menggunakan operator LINQ, dan membuat parameter konkurensi dalam aliran data asinkron menggunakan Penjadwal. Sederhananya, Rx = Observables + LINQ + Schedulers.

Ekstensi Reaktif berasal dari MSFT dan menerapkan banyak operator luar biasa yang menyederhanakan penanganan peristiwa. Itu open source hanya beberapa hari yang lalu. Ini sangat matang dan digunakan dalam produksi; menurut saya itu akan menjadi API yang lebih bagus untuk API Windows 8 daripada yang disediakan perpustakaan TPL; karena yang dapat diamati dapat berupa panas dan dingin dan dicoba kembali / digabungkan dll, sedangkan tugas selalu mewakili perhitungan panas atau selesai yang sedang berjalan, rusak atau selesai.

Saya telah menulis kode sisi server menggunakan Rx untuk asynchronocity, tetapi saya harus mengakui bahwa menulis secara fungsional di C # bisa sedikit mengganggu. F # memiliki beberapa pembungkus, tetapi sulit untuk melacak pengembangan API, karena grup tersebut relatif tertutup dan tidak dipromosikan oleh MSFT seperti proyek lainnya.

Sumber terbukanya datang dengan sumber terbuka dari kompiler IL-ke-JS, jadi mungkin bisa bekerja dengan baik dengan JavaScript atau Elm.

Anda mungkin bisa mengikat F # / C # / JS / Haskell bersama-sama dengan sangat baik menggunakan broker pesan, seperti RabbitMQ dan SocksJS.

Bling UI Toolkit - tautan

Deskripsi dari halaman depannya:

Bling adalah pustaka berbasis C # untuk dengan mudah memprogram gambar, animasi, interaksi, dan visualisasi di WPF / .NET Microsoft. Bling berorientasi pada teknolog desain, yaitu, desainer yang terkadang memprogram, untuk membantu dalam pembuatan prototipe cepat dari ide-ide desain UI yang kaya. Mahasiswa, seniman, peneliti, dan penghobi juga akan menganggap Bling berguna sebagai alat untuk mengekspresikan ide atau visualisasi dengan cepat. API dan konstruksi Bling dioptimalkan untuk pemrograman cepat kode yang dibuang sebagai lawan dari pemrograman kode produksi yang cermat.

Artikel LtU gratis .

Saya telah menguji ini, tetapi tidak bekerja dengannya untuk proyek klien. Kelihatannya luar biasa, memiliki operator C # yang kelebihan beban yang membentuk pengikatan antar nilai. Ini menggunakan properti ketergantungan di WPF / SL / (WinRT) sebagai sumber acara. Animasi 3D-nya bekerja dengan baik pada perangkat keras yang wajar. Saya akan menggunakan ini jika saya berakhir pada sebuah proyek yang membutuhkan visualisasi; mungkin mem-portingnya ke Windows 8.

ReactiveUI - link

Paul Betts, sebelumnya di MSFT, sekarang di Github, menulis kerangka kerja itu. Saya telah bekerja dengannya secara ekstensif dan menyukai modelnya. Ini lebih dipisahkan daripada Blink (berdasarkan sifatnya dari menggunakan Rx dan abstraksinya) - membuatnya lebih mudah untuk menguji kode unit menggunakannya. Klien github git untuk Windows ditulis di sini.

Komentar

Model reaktif cukup berkinerja untuk sebagian besar aplikasi yang menuntut kinerja. Jika Anda memikirkan hard real-time, saya berani bertaruh bahwa sebagian besar bahasa GC memiliki masalah. Rx, ReactiveUI membuat sejumlah objek kecil yang perlu di-GC, karena begitulah cara langganan dibuat / dibuang dan nilai-nilai antara dikembangkan dalam "monad" callback yang reaktif. Secara umum di .Net Saya lebih suka pemrograman reaktif daripada pemrograman berbasis tugas karena callback bersifat statis (diketahui pada waktu kompilasi, tidak ada alokasi) sementara tugas dialokasikan secara dinamis (tidak diketahui, semua panggilan memerlukan instance, sampah dibuat) - dan lambda dikompilasi menjadi kelas yang dihasilkan kompilator.

Jelas C # dan F # dievaluasi dengan ketat, jadi kebocoran waktu tidak menjadi masalah di sini. Sama untuk JS. Ini bisa menjadi masalah dengan observasi yang dapat diputar ulang atau disimpan dalam cache.

Henrik
sumber
Terima kasih atas jawaban yang bagus. Salah satu hal yang saya suka untuk implementasi FRP Haskell adalah bahwa mereka memungkinkan saya untuk memisahkan perhitungan untuk kontrol u(t)dan simulasinya dengan rapi f(t). Apakah itu kasus implementasi F #?
mnish
Saya kira Anda dapat mengatakan bahwa kedua fungsi itu dipisahkan untuk sementara, ya. Mereka mungkin tidak dipisahkan secara logis. ;)
Henrik
Sejauh yang saya tahu, Ekstensi Reaktif dan paket fokus UI lainnya yang lebih dipoles (dan segala sesuatu di luar Haskell, pada kenyataannya) hanya menggunakan semanik evented - artinya mereka memiliki gagasan tentang peristiwa yang dapat Anda aktifkan, tetapi bukan gagasan tentang sinyal waktu kontinu yang dapat berinteraksi secara sama. Untuk membangun guis ini baik-baik saja, menurutku. Namun, untuk simulasi dan model bangunan, hal ini mungkin disayangkan.
sclv
Apakah Anda menyiratkan bahwa semua implementasi lib pemrograman reaktif fungsional perlu memodelkan waktu secara terus menerus daripada secara diam-diam? Saya telah menemukan makalah yang berjudul "Aljabar Proses dengan Waktu: Waktu Nyata dan Waktu Diskrit" - apakah ini titik awal yang baik untuk memahami apa yang Anda bicarakan?
Henrik
Saya tidak mengatakan semua perlu - beberapa perlu, beberapa tidak. Tetapi mereka yang melakukannya lebih cocok untuk tugas-tugas tertentu, dan mereka yang tidak lebih cocok untuk yang lain ...
sclv