Haste
Same Language, Multiple latforms
Tagless Final Style
Same Syntax, Multiple nterpretations
Nathan Sorenson
@takeoutwe...
haste-lang.org
A Haskell-to-Javascript Compiler
created by Anton Ekblad
+ Full Haskell 2010 Support
(Proper Numbers, Lazy, Pure, Type Classes, …)
+ Nearly all GHC extensions
+ Supports large amo...
- No Template Haskell
- No GHCi
- No forkIO
- No Weak Pointers
Elm
Haskell-inspired. Strict. Structural typing and FRP.
Purescript
Haskell-inspired. Strict. Structural typing and Effect...
Browser-Friendly GHC-Compatible
Elm
PureScript
Fay GHCJSHaste
ghc-7.4.2.9: The GHC API
parseModule :: GhcMonad m => ModSummary → m ParsedModule
typeCheckModule :: GhcMonad m => ParsedM...
+---------+
LLVM backend /--->| LLVM IR |--
| +---------+ | LLVM
| v
+------------+ Desugar +------+ STGify +-----+ CodeGe...
module StgSyn where
data GenStgExpr bndr occ Source
= StgApp occ [GenStgArg occ]
| StgLit Literal
| StgConApp DataCon [Gen...
module Data.JSTarget.AST where
-- | Expressions. Completely predictable.
data Exp where
Var :: Var → Exp
Lit :: Lit → Exp
...
https://ghc.haskell.org/trac/ghc/ticket/3693
Installing
$ cabal install haste-compiler
$ haste-boot
# Or from source
$ git clone https://github.com/valderman/haste-com...
Building a Haste Project
$ hastec Main.hs # → Main.js
$ hastec --start=asap Main.hs # node Main.js
# Or with via cabal-ins...
Remove Haste Unfriendly Things
use Cabal build-type: Simple, not Custom
remove use of Template Haskell
remove use of ‘vect...
./libraries/haste-lib
module Haste.DOM
addChild :: MonadIO m => Elem → Elem → m ()
elemById :: MonadIO m => ElemID → m (Ma...
FFI
// javascript.js
function jsGetAttr(elem, prop) {
return elem.getAttribute(prop).toString();
}
-- haskell.hs (compile-...
facebook.github.io/react
<div id=“mydiv”>
<button>clickme</button>
</div>
React.DOM.div({idName:“mydiv”},
[React.DOM.button({},
[“clickme”])])
React.DOM.div({idName:“mydiv”},
[React.DOM.button({},
[“clickme”])])
<div id=“mydiv”>
<button>click{{me}}</button>
</div>
function(me) {
return React.DOM.div({idName:“mydiv”},
[React.DOM.button({},
[“click”+me])]);
}
<div id=“mydiv”>
<button>cl...
div :: [Attr] → [JSPtr] → JSPtr
button :: [Attr] → [JSPtr] → JSPtr
text :: String → JSPtr
EDSL
div :: [Attr] → [JSPtr] → JSPtr
button :: [Attr] → [JSPtr] → JSPtr
text :: String → JSPtr
EDSS
Embedded Domain Specific Sy...
Tagless Final Style
Tagless Final Style
Discovered by Oleg Kiselyov
Tagless Final Style
Discovered by Oleg Kiselyov
But don’t be scared.
Initial Style
data Html = Div [Attr] [Html]
| Button [Attr] [Html]
| Text String
client :: Html → JSPtr
client (Div attrs ...
server :: Html → String
server (Div attrs children) =
“<div” ++ show attrs ++ “>”
++ concatMap server children
++ “</div>”...
Initial Style
data Html =
Div [Attr] [Html]
| Button [Attr] [Html]
| Text String
class Html i where
div :: [Attr] → [ i ] → i
button :: [Attr] → [ i ] → i
text :: String → i
Final Style
Final Style
class Html i where
div :: [Attr] → [i] → i
button :: [Attr] → [i] → i
text :: String → i
-- Initial Style
data...
Final Style
class Html i where
div :: [Attr] → [i] → i
button :: [Attr] → [i] → i
text :: String → i
-- Initial Style (GAD...
Final Style
class Html i where
div :: [Attr] → [i] → i
button :: [Attr] → [i] → i
text :: String → i
instance Html String ...
srv :: Html→String
srv (Div attrs children) =
“<div” ++ show attrs ++ “>”
++ concatMap srv children
++ “</div>”
srv (Butto...
instance Html String where
div attrs children =
“<div” ++ show attrs ++ “>”
++ concatMap srv children
++ “</div>”
button a...
instance Html String where
-- div :: [Attr] → [i] → i
div attrs children =
“<div” ++ show attrs ++ “>”
++ concatMap ??? ch...
instance Html String where
-- div :: [Attr] → [i] → i
div attrs children =
“<div” ++ show attrs ++ “>”
++ concatMap id chi...
instance Html String where
-- div :: [Attr] → [i] → i
div attrs children =
“<div” ++ show attrs ++ “>”
++ concat children
...
-- Initial Style
i :: Html
i = Div [] [(Button [] [Text “clickMe”])]
iOut :: String
iOut = server i
-- Final Style
f :: (H...
class Math (i :: * ) where
lit :: Int → i
(+) :: i → i → i
(>) :: i → i → i
instance Math Int where …
instance Math String...
class Math (i :: *→*) where
lit :: Int → i Int
(+) :: i Int → i Int → i Int
(>) :: i Int → i Int → i Bool
class Math (i :: *→*) where
lit :: Int → i Int
(+) :: i Int → i Int → i Int
(>) :: i Int → i Int → i Bool
newtype Eval a =...
class Html i where
div :: [Attr] → [i] → i
button :: [Attr] → [i] → i
text :: String → i
instance SafariHtml String where
...
f :: (Html i, SafariHtml i) => i
f = div [] [(webkitElt [] [text “clickMe”])]
fOut = f :: String
Language Extensibility
div :: (Attr a, Html i) => [a] → [i] → i
-- div [idName “mydiv”] []
button :: (Attr a, Html i) => [a] → [i] → i
-- button ...
div :: (Html i) => [DivAttr] → [i] → i
-- div [idName “mydiv”] []
button :: (Html i) => [ButtonAttr] → [i] → i
-- button [...
type src form
<img>
instance
SrcA ImgAttr
<input>
instance
TypeA InputAttr
instance
SrcA InputAttr
instance
FormA InputAtt...
Typed Tagless Final Course Notes
okmij.org/ftp/tagless-final/course/lecture.pdf
haste-lang.org
“Haskell in the Browser Wit...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Syntax, Multiple Interpretations)
Upcoming SlideShare
Loading in …5
×

Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Syntax, Multiple Interpretations)

5,097 views

Published on

I discuss Haste, which compiles Haskell code to Javascript to be run on the browser. I then cover Tagless Final Style, which is a technique for creating flexible and extensible DSLs.

Published in: Software, Technology
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
5,097
On SlideShare
0
From Embeds
0
Number of Embeds
430
Actions
Shares
0
Downloads
15
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Syntax, Multiple Interpretations)

  1. 1. Haste Same Language, Multiple latforms Tagless Final Style Same Syntax, Multiple nterpretations Nathan Sorenson @takeoutweight i p
  2. 2. haste-lang.org A Haskell-to-Javascript Compiler created by Anton Ekblad
  3. 3. + Full Haskell 2010 Support (Proper Numbers, Lazy, Pure, Type Classes, …) + Nearly all GHC extensions + Supports large amount of Hackage + Cabal-style build + Compact output (~2k hello world) + Fast + Javascript FFI + Browser API
  4. 4. - No Template Haskell - No GHCi - No forkIO - No Weak Pointers
  5. 5. Elm Haskell-inspired. Strict. Structural typing and FRP. Purescript Haskell-inspired. Strict. Structural typing and Effect typing. Fay Haskell subset. Lazy. Small & Fast code. No type classes. GHCJS Full GHC. Big runtime with GC, Thread scheduler, etc
  6. 6. Browser-Friendly GHC-Compatible Elm PureScript Fay GHCJSHaste
  7. 7. ghc-7.4.2.9: The GHC API parseModule :: GhcMonad m => ModSummary → m ParsedModule typeCheckModule :: GhcMonad m => ParsedModule → m TypecheckedModu desugarModule :: GhcMonad m => TypecheckedModule → m DesugaredModule coreToStg :: DynFlags → CoreProgram → IO [ StgBinding ]
  8. 8. +---------+ LLVM backend /--->| LLVM IR |-- | +---------+ | LLVM | v +------------+ Desugar +------+ STGify +-----+ CodeGen +-----+ | NCG +----------+ | Parse tree |--------->| Core |-------->| STG |--------->| C-- |----+-------->| Assembly | +------------+ +------+ +-----+ +-----+ | +----------+ | ^ | +---+ | GCC C backend ---->| C |--/ +---+ https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/GeneratedCode ghc-7.4.2.9: The GHC API
  9. 9. module StgSyn where data GenStgExpr bndr occ Source = StgApp occ [GenStgArg occ] | StgLit Literal | StgConApp DataCon [GenStgArg occ] | StgOpApp StgOp [GenStgArg occ] Type | StgLam Type [bndr] StgExpr | StgCase (GenStgExpr bndr occ) (GenStgLiveVars occ) … | StgLet (GenStgBinding bndr occ) (GenStgExpr bndr occ) | StgLetNoEscape (GenStgLiveVars occ) (GenStgLiveVars … | StgSCC CostCentre !Bool !Bool (GenStgExpr bndr occ) | StgTick Module Int (GenStgExpr bndr occ)
  10. 10. module Data.JSTarget.AST where -- | Expressions. Completely predictable. data Exp where Var :: Var → Exp Lit :: Lit → Exp Not :: Exp → Exp BinOp :: BinOp → Exp → Exp → Exp Fun :: Maybe Name → [Var] → Stm → Exp Call :: Arity → Call → Exp → [Exp] → Exp Index :: Exp → Exp → Exp Arr :: [Exp] → Exp AssignEx :: Exp → Exp → Exp IfEx :: Exp → Exp → Exp → Exp deriving (Eq, Show)
  11. 11. https://ghc.haskell.org/trac/ghc/ticket/3693
  12. 12. Installing $ cabal install haste-compiler $ haste-boot # Or from source $ git clone https://github.com/valderman/haste-compiler.git $ cd haste-compiler $ cabal sandbox init $ cabal install $ haste-boot --local
  13. 13. Building a Haste Project $ hastec Main.hs # → Main.js $ hastec --start=asap Main.hs # node Main.js # Or with via cabal-install $ haste-inst configure $ haste-inst build # installing dependencies (if lucky) $ haste-inst install contravariant mtl semigroups
  14. 14. Remove Haste Unfriendly Things use Cabal build-type: Simple, not Custom remove use of Template Haskell remove use of ‘vector’ package # installing dependencies (if unlucky) $ cabal unpack time # … remove Haste Unfriendly Things … $ haste-inst configure $ haste-inst build --install-jsmods --ghc-options=-UHLINT $ haste-install-his time-1.4.2 dist/build $ haste-copy-pkg time-1.4.2 --package- db=dist/package.conf.inplace
  15. 15. ./libraries/haste-lib module Haste.DOM addChild :: MonadIO m => Elem → Elem → m () elemById :: MonadIO m => ElemID → m (Maybe Elem) module Haste.JSON encodeJSON :: JSON → JSString decodeJSON :: JSString → Either String JSON module Haste.Graphics.Canvas setFillColor :: Color → Picture () line :: Point → Point → Shape () module Haste.Concurrent.Monad forkIO :: CIO () → CIO () putMVar :: MVar a → a → CIO ()
  16. 16. FFI // javascript.js function jsGetAttr(elem, prop) { return elem.getAttribute(prop).toString(); } -- haskell.hs (compile-time ffi) foreign import ccall jsGetAttr :: Elem → JSString → IO JSString -- (in-line javascript, run-time ffi) f :: String → String → IO Int f a b = ffi “(function (a,b) {window.tst = a; return 3;})” a b -- expose to JS, via Haste[“myInc”] or Haste.myInc export :: FFI a => JSString → a → IO () export “myInc” ((x -> return (x + 1)) :: Int → IO Int) // javascript.js Haste.myInc(3) // 4
  17. 17. facebook.github.io/react
  18. 18. <div id=“mydiv”> <button>clickme</button> </div> React.DOM.div({idName:“mydiv”}, [React.DOM.button({}, [“clickme”])])
  19. 19. React.DOM.div({idName:“mydiv”}, [React.DOM.button({}, [“clickme”])]) <div id=“mydiv”> <button>click{{me}}</button> </div>
  20. 20. function(me) { return React.DOM.div({idName:“mydiv”}, [React.DOM.button({}, [“click”+me])]); } <div id=“mydiv”> <button>click{{me}}</button> </div>
  21. 21. div :: [Attr] → [JSPtr] → JSPtr button :: [Attr] → [JSPtr] → JSPtr text :: String → JSPtr EDSL
  22. 22. div :: [Attr] → [JSPtr] → JSPtr button :: [Attr] → [JSPtr] → JSPtr text :: String → JSPtr EDSS Embedded Domain Specific Syntax
  23. 23. Tagless Final Style
  24. 24. Tagless Final Style Discovered by Oleg Kiselyov
  25. 25. Tagless Final Style Discovered by Oleg Kiselyov But don’t be scared.
  26. 26. Initial Style data Html = Div [Attr] [Html] | Button [Attr] [Html] | Text String client :: Html → JSPtr client (Div attrs children) = … client (Button attrs children) = … client (Text str) = … server :: Html → String server (Div attrs children) = … server (Button attrs children) = … server (Text str) = … i i
  27. 27. server :: Html → String server (Div attrs children) = “<div” ++ show attrs ++ “>” ++ concatMap server children ++ “</div>” server (Button attrs children) = “<button” ++ show attrs ++ “>” ++ concatMap server children ++ “</button>” server (Text str) = str
  28. 28. Initial Style data Html = Div [Attr] [Html] | Button [Attr] [Html] | Text String
  29. 29. class Html i where div :: [Attr] → [ i ] → i button :: [Attr] → [ i ] → i text :: String → i Final Style
  30. 30. Final Style class Html i where div :: [Attr] → [i] → i button :: [Attr] → [i] → i text :: String → i -- Initial Style data Html = Div [Attr] [Html] | Button [Attr] [Html] | Text String
  31. 31. Final Style class Html i where div :: [Attr] → [i] → i button :: [Attr] → [i] → i text :: String → i -- Initial Style (GADT) data Html where Div :: [Attr] → [Html] → Html Button :: [Attr] → [Html] → Html Text :: String → Html
  32. 32. Final Style class Html i where div :: [Attr] → [i] → i button :: [Attr] → [i] → i text :: String → i instance Html String where div attrs children = … button attrs children = … text str = … instance Html JSPtr where div attrs children = … button attrs children = … text str = … i i
  33. 33. srv :: Html→String srv (Div attrs children) = “<div” ++ show attrs ++ “>” ++ concatMap srv children ++ “</div>” srv (Button attrs children) = “<button” ++ show attrs ++ “>” ++ concatMap srv children ++ “</button>” srv (Text str) = str
  34. 34. instance Html String where div attrs children = “<div” ++ show attrs ++ “>” ++ concatMap srv children ++ “</div>” button attrs children = “<button” ++ show attrs ++ “>” ++ concatMap srv children ++ “</button>” text str = str
  35. 35. instance Html String where -- div :: [Attr] → [i] → i div attrs children = “<div” ++ show attrs ++ “>” ++ concatMap ??? children ++ “</div>” -- button :: [Attr] → [i] → i button attrs children = “<button” ++ show attrs ++ “>” ++ concatMap ??? children ++ “</button>” -- text:: String → i text str = str
  36. 36. instance Html String where -- div :: [Attr] → [i] → i div attrs children = “<div” ++ show attrs ++ “>” ++ concatMap id children ++ “</div>” -- button :: [Attr] → [i] → i button attrs children = “<button” ++ show attrs ++ “>” ++ concatMap id children ++ “</button>” -- text:: String → i text str = str
  37. 37. instance Html String where -- div :: [Attr] → [i] → i div attrs children = “<div” ++ show attrs ++ “>” ++ concat children ++ “</div>” -- button :: [Attr] → [i] → i button attrs children = “<button” ++ show attrs ++ “>” ++ concat children ++ “</button>” -- text:: String → i text str = str
  38. 38. -- Initial Style i :: Html i = Div [] [(Button [] [Text “clickMe”])] iOut :: String iOut = server i -- Final Style f :: (Html i) => i f = div [] [(button [] [text “clickMe”])] fOut = f :: String
  39. 39. class Math (i :: * ) where lit :: Int → i (+) :: i → i → i (>) :: i → i → i instance Math Int where … instance Math String where … i i
  40. 40. class Math (i :: *→*) where lit :: Int → i Int (+) :: i Int → i Int → i Int (>) :: i Int → i Int → i Bool
  41. 41. class Math (i :: *→*) where lit :: Int → i Int (+) :: i Int → i Int → i Int (>) :: i Int → i Int → i Bool newtype Eval a = Eval {eval :: a} instance Math Eval where … newtype Pretty a = Pretty {pp :: String} instance Math Pretty where … a = (lit 1) > ((lit 2) + (lit 3)) e = eval a -- False p = pp a -- “(1 > (2 + 3))” i i
  42. 42. class Html i where div :: [Attr] → [i] → i button :: [Attr] → [i] → i text :: String → i instance SafariHtml String where webkitElt attrs children) = … instance SafariHtml JSPtr where webkitElt attrs children) = … class SafariHtml i where webkitElt :: [Attr] → [i] → i Language Extensibility i i
  43. 43. f :: (Html i, SafariHtml i) => i f = div [] [(webkitElt [] [text “clickMe”])] fOut = f :: String Language Extensibility
  44. 44. div :: (Attr a, Html i) => [a] → [i] → i -- div [idName “mydiv”] [] button :: (Attr a, Html i) => [a] → [i] → i -- button [idName “mybtn”, disabled True] [] class Attr a where idName :: String → a disabled :: Bool → a instance Attr DivAttr where idName s = … disabled b = … instance Attr ButtonAttr where idName s = … disabled b = … newtype ButtonAttr newtype DivAttr i i
  45. 45. div :: (Html i) => [DivAttr] → [i] → i -- div [idName “mydiv”] [] button :: (Html i) => [ButtonAttr] → [i] → i -- button [idName “mybtn”, disabled True] [] class IdA a where idName :: String → a class DisabledA a where disabled :: Bool → a instance IdA ButtonAttr where idName s = … instance DisabledA ButtonAttr where disabled b = … newtype ButtonAttrinstance IdA DivAttr where idName s = … newtype DivAttr i i i
  46. 46. type src form <img> instance SrcA ImgAttr <input> instance TypeA InputAttr instance SrcA InputAttr instance FormA InputAttr <button > instance TypeA ButtonAttr instance FormA ButtonAttr <label> instance FormA LabelAttr i i i i i i i
  47. 47. Typed Tagless Final Course Notes okmij.org/ftp/tagless-final/course/lecture.pdf haste-lang.org “Haskell in the Browser With Haste” Lars Kuhtz alephcloud.github.io/bayhac2014/slides facebook.github.io/react github.com/takeoutweight @takeoutweight

×