函數式響應式編程

維基百科,自由的百科全書

函數式響應式編程(FRP) 是一種編程範式,它採用函數式編程的基礎部件(如mapreducefilter等),進行響應式編程異步數據流程編程)。FRP被用於GUI機械人和音樂方面的編程,旨在通過顯式的建模時間來簡化這些問題。

FRP的形式[編輯]

函數式響應編程,自從1997年由Conal Elliott和保羅·胡達客在ICFP 97論文《函數式響應式動畫》中提出以來[1],產生了多種形式。其多樣性的一條軸線,是離散與連續語義對比。另一條軸線,是怎樣讓FRP系統可以動態地更改。[2]

連續[編輯]

FRP的最早形式採用了連續的語義,旨在抽象出對程序的意義無關緊要的操作細節。[1]這種形式的關鍵屬性為:

  • 建模在連續時間內變化的值,叫做「行為」,後來稱為「信號」。
  • 建模「事件」,它發生在離散的時間點上。
  • 系統可在響應事件時被改變,通用採用術語「切換」。
  • 從響應模型中分離出求值細節,如採樣率。

這種FRP語義模型在無副作用的語言中通常採用隨時間變化的連續函數。[3]

離散[編輯]

如事件驅動FRP和Elm在0.17版本之前的那種形式,它們要求更新過程是離散的,且由事件驅動。[4]這些形式在FRP的實踐中被加以推崇,它們專注於擁有簡單API的語義,比如在機械人或Web瀏覽器中可以被高效地實現。[5]

在這些形式下,行為和事件的概念通常會被合併成信號,它總是擁有當前值,但會被離散地改變。[6]

交互式FRP[編輯]

Conal Elliott在2008年已經指出,從輸入到輸出,這種普通的FRP模型,不太適合交互式程序。[7]在從輸入映射到輸出的過程中缺乏「運行」程序的能力,可能意味着必須使用以下解決方案之一:

  • 創建表示行動的一個數據結構,它表現為輸出。行動必須被一個外部的解釋器或環境來運行。它繼承了最初Haskell的流式I/O的全部難點。[8]
  • 使用箭頭英語Arrow (computer science)化的FRP,和有能力實行行動的嵌入箭頭。行動也必須有身份標識,比如說使得它們可以做維護各自的可變存儲。採取這種辦法的是Fudgets庫[9],和更一般性的單子流函數[10]
  • 最新穎的方法就是允許行動現在運行(於IO單子中),但將它們結果的接收推遲到以後。[11]它利用了事件和IO單子之間的交互,併兼容於更加面向表達式的FRP:
planNow :: Event (IO a) -> IO (Event a)

實現問題[編輯]

存在兩種類型的FRP系統,基於推送的和基於拉取的。基於推送的系統接收事件,並將它們推過一個信號網絡來達成結果。基於拉取的系統會等待對結果的需求,並逆向通過該網絡檢索所需求的值。

某些FRP系統例如Yampa使用採樣,這裏將採樣推過一個信號網絡。這種方法有個缺點:網絡在一個計算步驟持續期間必須等待,然後才能發現輸入上的變更。採樣就是個基於推送的FRP示例。

Hackage上的Reactive和Etage庫介入了一種叫做「推送-拉取FRP」的方式。按照這種方式,只在需求純粹定義的流(如隨時間推移的固定事件的列表)上的下一個事件時,才會構造該事件。這些純粹定義的流的行為類似於Haskell中的惰性列表。此為基於拉取的部分。基於推送的部分會在系統外部的事件被帶入系統時使用到。外部的事件會被推送給消費者,這樣它們就可以在它發佈的瞬間找到該事件。

實現[編輯]

  • Yampa[12],是一個箭頭化、高效的、純Haskell實現,支持SDL、SDL2、OpenGL和HTML DOM。
  • reflex[13],是一個高效的,用Haskell實現的推送/拉取式FRP,主要宿主是瀏覽器/DOM、SDL和Gloss。
  • reactive-banana[14],是一個用Haskell實現的目標不可知的推送式FRP。
  • netwire[15]和varying[16],是箭頭化的,用Haskell實現的拉取式FRP。
  • Flapjax,是一個用JavaScript實現的行為/事件式FRP。
  • React[17],是用於函數式響應編程的一個OCaml模塊。
  • Sodium[18],是獨立於UI框架的推送式FRP實現,支持多種程式語言比如Java、TypeScript和C#。
  • ReactiveX英語ReactiveX,由它的JavaScript實現rxjs[19]而流行,是實現函數式響應式編程的綜合性跨平台范型,將數據當作可觀測者的流來處理。
  • Dunai[20],是支持類和箭頭化FPR的,使用單子流函數的一個Haskell的快速實現。

另請參閱[編輯]

  • Elm程式語言,曾經支持FRP[21],但是現在以不同的模式替代了它[22]
  • Ur程式語言,瀏覽器客戶端包括了函數式響應式編程設施。
  • 增量計算
  • 串流處理

參考來源[編輯]

  1. ^ 1.0 1.1 Elliott, Conal; Hudak, Paul, Functional Reactive Animation, ICFP, 1997 [2018-04-13], (原始內容存檔於2020-11-11) .
  2. ^ Nilsson, Henrik; Courtney, Antony; Peterson, John, Functional Reactive Programming, Continued (PDF), Haskell Workshop (PDF) (2), Feb 2011 [2002] [2018-04-13], (原始內容 (PDF)存檔於2017-10-10) .
  3. ^ Courtney, Antony; Elliott, Conal, Genuinely Functional User Interfaces, Haskell Workshop, Yale, Feb 2011 [2001] [2018-04-13], (原始內容存檔於2022-04-13) .
  4. ^ Taha, Walid; Wan, Zhanyong; Hudak, Paul, Event-Driven FRP, PADL, Yale, 2002 [2021-03-02], (原始內容存檔於2021-02-10) .
  5. ^ Czaplicki, Evan; Chong, Stephen, Asynchronous Functional Reactive Programming for GUIs, PLDI, Harvard, 2013 [2018-04-13], (原始內容存檔於2018-11-09) .
  6. ^ Wan, Zhanyong; Taha, Walid; Hudak, Paul, Real-Time FRP, ICFP (PDF) (1), Feb 2011 .
  7. ^ Why classic FRP does not fit interactive behavior. [2018-04-13]. (原始內容存檔於2015-07-24). 
  8. ^ Alan Borning1CSE 505I/O in Purely Functional Languages (PDF). [2018-04-13]. (原始內容存檔 (PDF)於2016-05-28). 
  9. ^ The Fudgets Thesis on WWW. [2018-04-13]. (原始內容存檔於2020-01-24). 
  10. ^ Perez, Ivan; Barenz, Manuel; Nilsson, Henrik, Functional Reactive Programming, Refactored, Haskell Symposium (PDF), July 2016 [2021-03-02], (原始內容存檔 (PDF)於2017-05-18) .
  11. ^ Atze van der Ploeg; Koen Claessen. Practical Principled FRP-Forget the past, change the future, FRPNow!. [2021-03-04]. (原始內容存檔於2020-04-25). 
  12. ^ Yampa. [2021-03-02]. (原始內容存檔於2021-03-01). 
  13. ^ reflex. [2018-04-13]. (原始內容存檔於2020-11-11). 
  14. ^ reactive-banana. [2018-04-13]. (原始內容存檔於2020-11-11). 
  15. ^ netwire. [2018-04-13]. (原始內容存檔於2020-10-20). 
  16. ^ varying. [2018-04-13]. (原始內容存檔於2020-11-12). 
  17. ^ React. [2021-03-02]. (原始內容存檔於2020-12-24). 
  18. ^ Sodium. [2021-03-02]. (原始內容存檔於2020-12-24). 
  19. ^ rxjs. [2021-03-02]. (原始內容存檔於2021-05-17). 
  20. ^ Dunai. [2021-03-02]. (原始內容存檔於2021-05-24). 
  21. ^ Czaplicki, Evan, Elm: Concurrent FRP for Functional GUIs (PDF) (thesis), Harvard, Apr 2012 [2021-03-02], (原始內容存檔 (PDF)於2021-04-16) .
  22. ^ Czaplicki, Evan. A Farewell to FRP. elm. [14 July 2018]. (原始內容存檔於2019-05-31). 

外部連結[編輯]