Practical Frontend with Haskell and Refex FRP Sergey Bushnyak @sigrlami
JavaScript Default language of choice for web UIs ● Widespread usage ●
The JavaScript problem Dynamic T ypes ● Mutability ● Callback hell ●
The JavaScript problem : Callback Hell Observer : Unpredictable order ● Observer : Inconsistent state ● Observer : Leaking listeners ● Observer : Forced Single Threading ●
The JavaScript problem : Dynamic T ypes Dynamic typing ● Nice for developers / easy to change things – Error prone / unexpected result while combining types – Require experience to create proper abstractions –
The JavaScript problem But there are Promise for that ● → also easy to end up in a Promise hell (especially for complex application) But there is React + T ypescript ● → good, but still inconistency in states Bigger codebase → bigger complexity to handle ●
Solutions Landscape React + T ypescript ● Other languages ● ClojureScript – Elm – Opa – Haskell based ● PureScript – Haste – Refex/GHCJS – Many other attempts (Fay, Roy, Halogen, ..) –
FRP / Functional Reactive Programming FRP to Rescue ● Look from Haskell based view ●
FRP / Functional Reactive Programming 1997 – Conant Elliot / events handling ● 2000 – Paul Hudak / orderdered timing ● 2009 – Conan Elliot / push-pull ● 2012 - Evan Czaplicki / elm ●
FRP / Functional Reactive Programming Event ● Behavior ●
FRP / Use Cases UI (stream of user events) ● Robotics (stream of sensors events) ● Electronics (net tracing and wiring) ●
GHCJS / Refex Refex is FRP specifcation and realisation ● Builds Up a platform `refex-platform` https://github.com/refex-frp ● `refex` – `refex-dom` – `refex-contrib` –
GHCJS GHCJS is GHC compiled to JavaScript ● Not a subset or implementation or partial functionality ● Everything non-C based (tcp networking) compiled as is ●
GHCJS Means you can share functiionality ● Means you can use Haskell idioms in JavaScript world ●
Refex / bbstractions Event ● Behavior ● Dynamic ●
Refex / Functions never :: Event a ● hold :: a → Event a → m (Behaviour a) ● tag :: Behaviour a → Event b → Event a ● attach :: Behaviour a → Event b → Event (a, b) ● attachWith :: (a → b → c) → Behaviour a → Event b → Event c ● switch :: Behaviour (Event a) → Event a ●
Refex / Functions constDyn :: a → Dynamic a ● constructor – holdDyn :: a → Event a → m (Dynamic a) ● constructor – foldDyn :: (a → b → b) → b → Event a → m (Dynamic b) ● constructor – current :: Dynamic a → Behavior a ● accessor – updated :: Dynamic a → Event a ● accessor –
Refex Use Cases Soostone, Inc. ~ 15k loc webapp ● T akt, Inc. / Foundation.ai ~ 22k loc webapp ● Obsydian Systems, Inc. ~ 3k – 20k loc webapps ● Kelecorix, Inc. ~ 2-6k loc webapps ●
Refex / Higher Order FRP Nesting widgets ● widgetHold :: m a → Event (m a) → m (Dynamic a) – dyn :: Dynamic (m a) → m (Event a) – Collapsing action ● Usually `join` –
Refex / Current issues Building (Stack vs Nix); ● Better routing for complex applications ● bpp size (partually fxes with Closure compiler in a pipeline) ● GHCJS state ●
Shared code
The End
Recommend
More recommend