Ur/Web, a Domain-Specific Functional Programming Language for Modern Web Applications Adam Chlipala Web Applications: A Steaming Pile of Text HTML, CSS, JavaScript, SQL, URLs, JSON, ... Web App Developer Strings, strings, strings, ... Compiler/Interpreter Saner Languages/Frameworks ● Links ● Ocsigen ● LINQ ● WebSharper ● OPA (“One-Pot Application”) ● ...? 3 Executive Summary Ur/Web is a domain-specific language with a fancy static type system with first-class support for Web app architecture including strong encapsulation and statically-checked metaprogramming with security by construction Hello World! fun main () = return Hello world!

Hello world!

5 Strong Encapsulation Insert Lookup Hash Table Module Interface Client Code 6 Web 1.0 Encapsulation Users Database Table Login Cookie Module Interface Client Code 7 Encapsulation structure Auth : sig val loginForm : unit ­> xbody val whoami : unit ­> string end = struct table users : {Nam : string, Pw : string} cookie auth : {Nam : string, Pw : string} fun rightInfo r = oneRow (SELECT COUNT(*) FROM users WHERE Nam = {[r.Nam]} AND Pw = {[r.Pw]}) = 1 fun login r = if rightInfo r then setCookie auth r else error “Wrong info!” fun loginForm () = (* Form handled by 'login'... *) fun whoami () = let r = getCookie auth in if rightInfo r then r.Nam else error “Wrong info!” end 8 Some Client Code fun main () = return {Auth.loginForm ()}

Welcome. You could go somewhere.

and somewhere () = user <­ Auth.whoami (); if user = “Fred Flintstone” then return Yabba dabba doo! else return Boring and evil () = oneRow (SELECT Pw FROM Auth.user WHERE Nam = 'Admin') 9 Web 2.0 Encapsulation Subtree of Dynamic Page Structure Module Interface Client Code 10 Functional-Reactive GUIs The Status Quo: A B The Reactive Way: Document Tree (DOM) Change the value of this data source. Script C Data Source Find the node named “B” and replace its contents. D .... Data Source Module Pure Function A B Script D C D 11 A Client-Side Counter structure Counter : sig type t val new : unit ­> t val increment : t ­> unit val render : t ­> xbody end = struct type t = source int fun new () = source 0 fun increment c = n <­ get c; set c (n + 1) fun render c = {[n]}}/> end 12 Counter Client fun main () = c <­ Counter.new (); return {Counter.render c}