Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Halogen: Past, Present, Future
John A. De Goes — @jdegoes
Agenda
• Functional Frontend: SlamData
• FRP & React
• Common Elements
• FRP in a Type
• React in a Type
• The 100k Proble...
Functional Frontend:
SlamData
• Visual analytics for NoSQL
• Analytic workflows
• Data exploration
• Data visualization
• ...
Data Visualization
We'll get back to that.
FRP & React
Common Elements
data HTML i
= Text String
| Element TagName (A.Attribute i) (Array (HTML i))
data HTML
= Text ...
FRP & React
FRP in a Type
data Signal a = Signal (Time -> a)
instance applicativeSignal :: ...
myApp :: Signal HTML
myApp ...
FRP & React
React in a Type
data React s m i
= React { render :: s -> HTML i,
update :: i -> s -> m s }
myApp :: React MyS...
The 100k Problem
Look Closely...
Signal HTML
s -> HTML a
Types necessarily imply a potentially massive, in-memory HTML
str...
The 100k Problem
Diffing
diff :: HTML -> HTML -> HTMLPatch
Diffing only helps with the DOM updates, nothing else!
The 100k Problem
Data Visualization
Neither React nor FRP offer a performant means of incrementally
visualizing large data...
Halogen: Past
History
• Popular, production-ready UI library for PureScript
• Commissioned by SlamData
• Blank-slate desig...
Halogen: Past
Signal Functions
data HTML i = ...
newtype SF i o = SF (i -> SF1 i o)
newtype SF1 i o = SF1 { result :: o, n...
Halogen: Past
If You Squint...
type Function i o = i -> o
type UI i = Cofree (Function i) (HTML i)
Halogen: Present
View + DSL
type Component s f g =
{ view :: s -> HTML (f Unit),
eval :: forall a. f a -> (HalogenDSL s g)...
Halogen: Present
In Practice
• Strongly-typed component-driven design
• Structure of entire app is encoded in type (!!!)
•...
Halogen: Future
Next-Generation Goals
• Built on a foundation of incremental computation
• Turtles all the way down — no m...
Halogen: Future
Incremental React???
data React s m i
= React { render :: s -> HTML i,
update :: i -> s -> m s }
data DRea...
Halogen: Future
Simplify
data UI s p i ds
= UI { render :: s -> p i ds, -- Push "effects" here!
update :: s -> ds -> s } -...
Halogen: Future
Profunctor Algebras
data File a b
= ReadByte (a -> Byte)
| WriteByte Byte (Unit -> b)
Halogen: Future
Profunctor Algebras
Contravariant
|
data File a b
= ReadByte (a -> Byte)
| WriteByte Byte (Unit -> b)
Halogen: Future
Profunctor Algebras
Covariant
|
data File a b
= ReadByte (a -> Byte)
| WriteByte Byte (Unit -> b)
Halogen: Future
Profunctor Algebras
data FreePro p a b -- :: (* -> * -> *) -> * -> * -> *
A computation in p that reads 0-...
Halogen: Future
Profunctor Algebras
data File a b
= ReadByte (a -> Byte)
| WriteByte Byte (Unit -> b)
readByte :: FreePro ...
Halogen: Future
Profunctor Algebras
data DOM i o
= ListenEvent Id EventType (i -> Event)
| AppendChild Id (Id -> o)
| ...
Halogen: Future
Profunctor Algebras
data UI s p i ds
= UI { render :: s -> p i ds,
update :: s -> ds -> s }
type FreeDOM a...
Halogen: Future
Components
data TextDiff
= Insert Int String
| Delete Int Int
textField :: Component String TextDiff
*Can ...
Halogen: Future
Lens-ish
data Nest ds' s' ds s = Nest (PrismP ds' ds) (LensP s' s)
The nesting of a smaller state differen...
Halogen: Future
Combinators
embed :: forall ds' s' ds s. Nest ds' s' ds s -> Components ds' s' -> Components ds s
siblings...
Halogen: Future
Example
data FormDiff = Email TextDiff | Password TextDiff
type FormState = { email :: String, password ::...
Conclusion
• Practical requirements suggest an incremental theory of UI
• FRP and React are problematic
• A coinductive, p...
THANK YOU!
John A. De Goes — @jdegoes
Upcoming SlideShare
Loading in …5
×

of

Halogen: Past, Present, and Future Slide 1 Halogen: Past, Present, and Future Slide 2 Halogen: Past, Present, and Future Slide 3 Halogen: Past, Present, and Future Slide 4 Halogen: Past, Present, and Future Slide 5 Halogen: Past, Present, and Future Slide 6 Halogen: Past, Present, and Future Slide 7 Halogen: Past, Present, and Future Slide 8 Halogen: Past, Present, and Future Slide 9 Halogen: Past, Present, and Future Slide 10 Halogen: Past, Present, and Future Slide 11 Halogen: Past, Present, and Future Slide 12 Halogen: Past, Present, and Future Slide 13 Halogen: Past, Present, and Future Slide 14 Halogen: Past, Present, and Future Slide 15 Halogen: Past, Present, and Future Slide 16 Halogen: Past, Present, and Future Slide 17 Halogen: Past, Present, and Future Slide 18 Halogen: Past, Present, and Future Slide 19 Halogen: Past, Present, and Future Slide 20 Halogen: Past, Present, and Future Slide 21 Halogen: Past, Present, and Future Slide 22 Halogen: Past, Present, and Future Slide 23 Halogen: Past, Present, and Future Slide 24 Halogen: Past, Present, and Future Slide 25 Halogen: Past, Present, and Future Slide 26 Halogen: Past, Present, and Future Slide 27 Halogen: Past, Present, and Future Slide 28 Halogen: Past, Present, and Future Slide 29 Halogen: Past, Present, and Future Slide 30 Halogen: Past, Present, and Future Slide 31
Upcoming SlideShare
Getting Started with PureScript
Next
Download to read offline and view in fullscreen.

5 Likes

Share

Download to read offline

Halogen: Past, Present, and Future

Download to read offline

Halogen is a popular choice for building front-end user-interfaces with PureScript. Often described as a purely functional version of React, Halogen allows building user-interfaces by composing declarative, self-contained components, including effectful components those built from third-party Javascript libraries.

In this presentation, John presents a high-level summary of where Halogen has come from, how it works right now, and what are the main drawbacks to both FRP and React. John then suggests that incremental computation should be the foundation for the next major version of Halogen, and sketches out a possible way of achieving that in a declarative fashion.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

Halogen: Past, Present, and Future

  1. 1. Halogen: Past, Present, Future John A. De Goes — @jdegoes
  2. 2. Agenda • Functional Frontend: SlamData • FRP & React • Common Elements • FRP in a Type • React in a Type • The 100k Problem • Turtles • Halogen: Introduction • Halogen: Past • Halogen: Present • Halogen: Future • Conclusion
  3. 3. Functional Frontend: SlamData • Visual analytics for NoSQL • Analytic workflows • Data exploration • Data visualization • 100% PureScript • 248 modules • Largest known PureScript project in the world • Currently five full-time developers
  4. 4. Data Visualization We'll get back to that.
  5. 5. FRP & React Common Elements data HTML i = Text String | Element TagName (A.Attribute i) (Array (HTML i)) data HTML = Text String | Element TagName A.Attribute (Array HTML)
  6. 6. FRP & React FRP in a Type data Signal a = Signal (Time -> a) instance applicativeSignal :: ... myApp :: Signal HTML myApp = ...
  7. 7. FRP & React React in a Type data React s m i = React { render :: s -> HTML i, update :: i -> s -> m s } myApp :: React MyState EffectMonad MyEvent myApp = ...
  8. 8. The 100k Problem Look Closely... Signal HTML s -> HTML a Types necessarily imply a potentially massive, in-memory HTML structure that can neither be created nor updated incrementally.
  9. 9. The 100k Problem Diffing diff :: HTML -> HTML -> HTMLPatch Diffing only helps with the DOM updates, nothing else!
  10. 10. The 100k Problem Data Visualization Neither React nor FRP offer a performant means of incrementally visualizing large data sets. Rendering or even storing that much data is prohibitive.
  11. 11. Halogen: Past History • Popular, production-ready UI library for PureScript • Commissioned by SlamData • Blank-slate design originally architected by Phil Freeman • Powers the SlamData application
  12. 12. Halogen: Past Signal Functions data HTML i = ... newtype SF i o = SF (i -> SF1 i o) newtype SF1 i o = SF1 { result :: o, next :: SF i o } type UI i = SF1 i (HTML i) runUI :: forall i eff. UI i -> Eff (HalogenEffects eff) Node
  13. 13. Halogen: Past If You Squint... type Function i o = i -> o type UI i = Cofree (Function i) (HTML i)
  14. 14. Halogen: Present View + DSL type Component s f g = { view :: s -> HTML (f Unit), eval :: forall a. f a -> (HalogenDSL s g) a } Grossly simplified. :)
  15. 15. Halogen: Present In Practice • Strongly-typed component-driven design • Structure of entire app is encoded in type (!!!) • ...And therefore static (pros & cons) • Types get complex, but reasoning is level-by-level • Hard to get compiling, but then usually works
  16. 16. Halogen: Future Next-Generation Goals • Built on a foundation of incremental computation • Turtles all the way down — no magic • Native expressivity — no need for escape hatch • Unify web components with ordinary HTML "components" (elements) • Simplify types a little? :)
  17. 17. Halogen: Future Incremental React??? data React s m i = React { render :: s -> HTML i, update :: i -> s -> m s } data DReact s ds m i = DReact { render :: s -> ds -> ΔHTML i, effect :: i -> s -> m ds, update :: s -> ds -> s }
  18. 18. Halogen: Future Simplify data UI s p i ds = UI { render :: s -> p i ds, -- Push "effects" here! update :: s -> ds -> s } -- Monoid action! • Rendering produces a machine that reads is and produces a state change. • Updating produces a new state given an old state and a state change.
  19. 19. Halogen: Future Profunctor Algebras data File a b = ReadByte (a -> Byte) | WriteByte Byte (Unit -> b)
  20. 20. Halogen: Future Profunctor Algebras Contravariant | data File a b = ReadByte (a -> Byte) | WriteByte Byte (Unit -> b)
  21. 21. Halogen: Future Profunctor Algebras Covariant | data File a b = ReadByte (a -> Byte) | WriteByte Byte (Unit -> b)
  22. 22. Halogen: Future Profunctor Algebras data FreePro p a b -- :: (* -> * -> *) -> * -> * -> * A computation in p that reads 0-to-many a's and produces a single b. • Functor, Apply, Applicative, Monad (if desired) • Profunctor
  23. 23. Halogen: Future Profunctor Algebras data File a b = ReadByte (a -> Byte) | WriteByte Byte (Unit -> b) readByte :: FreePro File Byte Byte readByte = liftFP $ ReadByte id writeByte :: forall a. Byte -> FreePro a Unit writeByte b = liftFP $ WriteByte b id
  24. 24. Halogen: Future Profunctor Algebras data DOM i o = ListenEvent Id EventType (i -> Event) | AppendChild Id (Id -> o) | ...
  25. 25. Halogen: Future Profunctor Algebras data UI s p i ds = UI { render :: s -> p i ds, update :: s -> ds -> s } type FreeDOM a b = FreePro DOM a b type Component s ds = UI s FreeDOM DOMEvent ds
  26. 26. Halogen: Future Components data TextDiff = Insert Int String | Delete Int Int textField :: Component String TextDiff *Can be more polymorphic!
  27. 27. Halogen: Future Lens-ish data Nest ds' s' ds s = Nest (PrismP ds' ds) (LensP s' s) The nesting of a smaller state differential inside a larger one.
  28. 28. Halogen: Future Combinators embed :: forall ds' s' ds s. Nest ds' s' ds s -> Components ds' s' -> Components ds s siblings :: forall s ds. Component s ds -> Component s ds -> Component s ds child :: forall s ds. Component s ds -> Component s ds -> Component s ds infix 5 siblings as <~> infix 6 child as </>
  29. 29. Halogen: Future Example data FormDiff = Email TextDiff | Password TextDiff type FormState = { email :: String, password :: String } webForm :: Component FormState FormDiff webForm = div </> embed _Email (label "Email" <~> textField) <~> div </> embed _Password (label "Password" <~> passwordField) _Email :: Nest String TextDiff FormState FormDiff _Password :: Nest String TextDiff FormState FormDiff
  30. 30. Conclusion • Practical requirements suggest an incremental theory of UI • FRP and React are problematic • A coinductive, profunctor-based approach looks promising • But some details yet to be worked out... • Halogen 1.0 is coming, & you can help!
  31. 31. THANK YOU! John A. De Goes — @jdegoes
  • FrederickRoos

    Oct. 3, 2019
  • AttilaGulyas

    Feb. 21, 2017
  • henriknorberg

    Oct. 5, 2016
  • sectore

    Jun. 13, 2016
  • JarleStabell

    Jun. 12, 2016

Halogen is a popular choice for building front-end user-interfaces with PureScript. Often described as a purely functional version of React, Halogen allows building user-interfaces by composing declarative, self-contained components, including effectful components those built from third-party Javascript libraries. In this presentation, John presents a high-level summary of where Halogen has come from, how it works right now, and what are the main drawbacks to both FRP and React. John then suggests that incremental computation should be the foundation for the next major version of Halogen, and sketches out a possible way of achieving that in a declarative fashion.

Views

Total views

2,831

On Slideshare

0

From embeds

0

Number of embeds

126

Actions

Downloads

10

Shares

0

Comments

0

Likes

5

×