Phil Freeman
April 10, 2018
780

# Incremental Programming in PureScript

April 10, 2018

## Transcript

Stamp’;
4. ### Why? SELECT SUM(orders.total) FROM orders JOIN customer ON customers.id =

orders.customer_id WHERE customer.state = ‘CA’;
5. ### Idea Instead, we can try to compute changes in outputs

from changes in inputs.
6. None
7. ### Incremental Lambda Calculus Extend types with change structures Change structures

are monoids of changes which act on their carrier types (transitively).
8. ### In Brief class Patch a da ⇐ Diff a da

| a → da where diff :: a → a → da instance Diff Unit Unit instance (Diff a da, Diff a db) ⇒ Patch (Diff a b) (Diff da db) instance (Diff a da, Diff a db) ⇒ Diff (a → b) (a → da → db) instance Diff a da ⇒ Diff (Bag a) (Bag da) class Monoid da ⇐ Patch a da | a → da where patch :: a → da → a instance Patch Unit Unit instance (Patch a da, Patch a db) ⇒ Patch (Tuple a b) (Tuple da db) instance (Patch a da, Patch a db) ⇒ Patch (a → b) (a → da → db) instance Patch a da ⇒ Patch (Bag a) (Bag da)
9. ### A Theory of Changes for Higher-Order Languages Interpret each type

as a type and a change structure Construct a source-to-source transformation to interpret terms
10. ### purescript-incremental Defines an embedded DSL for incremental programs • Uses

higher-order abstract syntax • Inspired by automatic differentiation
11. ### purescript-incremental unjet :: (Jet a da → Jet b db)

→ Tuple (a → b) (a → da → db) unjet jf = Tuple f df where f a = b where Jet b _ = jf (Jet a mempty) df a da = db where Jet _ db = jf (Jet a da) jet :: (a → b) → (a → da → db) → Jet a da → Jet b db jet f df (Jet a da) = Jet (f a) (df a da) data Jet a da = Jet a da
12. ### Embedding We require that patch (f₀ a) db = f₀

(patch a da) whenever Jet _ db = f (Jet a da) Tuple f₀ _ = unjet f “Constant” jet functions also satisfy snd (f (Jet a mempty)) = mempty Represent a function a → b by f :: Jet a da → Jet b db
13. ### Example map :: (Jet a da -> Jet b db)

→ Jet (IMap k a) _ → Jet (IMap k b) _ filter :: (Jet a da -> Jet Boolean _) → Jet (IMap k a) _ → Jet (IMap k a) _ join :: Jet (IMap k a) _ → Jet (IMap k b) _ → Jet (IMap k (Tuple a b)) _ Embedded incremental relational algebra! data IMap k v data MapChange v dv = Add v | Remove | Update dv type MapChanges k v dv = Map k (Array (MapChange v dv)) instance Patch v dv ⇒ Patch (IMap k v) (MapChanges k v dv)
14. ### Incremental DOM newtype ViewChanges eff = ViewChanges { text ::

Last String , attrs :: MapChanges String (Atomic String) (Last String) , handlers :: MapChanges String (Atomic (EventListener eff)) (Last (EventListener eff)) , kids :: Array (ArrayChange (View eff) (ViewChanges eff)) } Translate model changes directly into DOM updates. See purescript-purview. newtype View eff = View { element :: String , text :: Atomic String , attrs :: IMap String (Atomic String) , handlers :: IMap String (Atomic (EventListener eff)) , kids :: IArray (View eff) }
15. ### Stuff to think about • Some similar DOM libraries ◦

paf31/purescript-sdom ◦ i-am-tom/purescript-panda • Implement this in the database • Incremental parsing • Incremental canvas graphics Questions?