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:
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?
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?
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?
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!
Meskipun sudah ada beberapa jawaban yang bagus, saya akan mencoba menjawab pertanyaan spesifik Anda.
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.
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.
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
Monad
contoh 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.
sumber
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:
Ini memiliki varian FRP sendiri . Dari bermain-main dengan contoh-contohnya, tampaknya cukup dewasa.
Ekstensi Reaktif - tautan
Deskripsi dari halaman depannya:
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:
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.
sumber
u(t)
dan simulasinya dengan rapif(t)
. Apakah itu kasus implementasi F #?