Linguistic Abstraction for the Web

67
Eelco Visser http://eelcovisser.org Linguistic Abstraction for the Web Mountain View June 8, 2011

description

Slides used in TechTalk at Google Mountain View on June 8, 2011

Transcript of Linguistic Abstraction for the Web

Page 1: Linguistic Abstraction for the Web

Eelco Visserhttp://eelcovisser.org

Linguistic Abstraction for the Web

Mountain ViewJune 8, 2011

Page 2: Linguistic Abstraction for the Web

Messages

Linguistic abstraction as software engineering tool

Web languages can be improved

Page 3: Linguistic Abstraction for the Web

bridging the gap between problem domain and solution domain

Software Engineering

ProblemDomain Machine

Page 4: Linguistic Abstraction for the Web

HLLs reduce gap

High-Level Languages

ProblemDomain HLL Machine

"A programming language is low level when its programs require attention to the irrelevant." Alan J. Perlis (1982)

Page 5: Linguistic Abstraction for the Web

domain-specific languages support more specialization

Domain-Specific Languages

ProblemDomain HLL MachineDSL

Page 6: Linguistic Abstraction for the Web

Software Language Design & Engineering

enable software engineers to effectively design, implement, and apply domain-specific

software languages

Page 7: Linguistic Abstraction for the Web

Research: Software Language Engineering

Automatically derive efficient, scalable, incremental compiler +

usable IDE from high-level,

declarative language definition

Page 8: Linguistic Abstraction for the Web

creating full featured IDEs for domain-specific languages

The Spoofax Language Workbench

Page 9: Linguistic Abstraction for the Web

Research: Software Language Design

Systematically design domain-

specific software languages with optimal tradeoff between expressivity,

completeness, portability, coverage, and maintainability

Page 10: Linguistic Abstraction for the Web

Software Language Design Case Studies

Mobl: client-side stateful web applications

WebDSL: server-side restful web applications

Page 11: Linguistic Abstraction for the Web

http://webdsl.org

Eelco Visser, Danny Groenewegen, et al.

Page 12: Linguistic Abstraction for the Web

browser server database

web app

Web Programming

Page 13: Linguistic Abstraction for the Web

code runs on server, browser, and database

browser server database

Java

Web Programming

SQLHTML, JS, CSS

Page 14: Linguistic Abstraction for the Web

Concerns in Web Programming

❖ Persistent data

★ data integrity

★ search

❖ User interface

★ data validation

★ styling, layout

★ navigation

★ actions

❖ Access control

Page 15: Linguistic Abstraction for the Web

Separation of Concerns in Web Programming

Example

❖ Data modeling

★ Java classes with JPA annotations

❖ User interface

★ Java ServerFaces XML templates

★ Seam Java classes

❖ Access control

★ Acegi configuration/annotation

Page 16: Linguistic Abstraction for the Web

Problems in Web Programming

❖ Lack of integration

★ no cross language/concern consistency checking

★ leads to late (detection of) failures

❖ Low-level encoding

★ leads to boilerplate code

Page 17: Linguistic Abstraction for the Web

When Seam Fails

Welcome #{user.name} Welcome #{user.nam}

Page 18: Linguistic Abstraction for the Web

When Rails Fails

@post = Post.new(params[:post])

@post = Post.new(params[:get])

Page 20: Linguistic Abstraction for the Web

Separation of Concerns + Linguistic Integration

Page 21: Linguistic Abstraction for the Web

WebDSL Example

Page 22: Linguistic Abstraction for the Web

Model-View Pattern

Page 23: Linguistic Abstraction for the Web

Model

Page 24: Linguistic Abstraction for the Web

entity Blog { key :: String (id) title :: String (name) posts -> Set<Post> (inverse=Post.blog)}entity Post { key :: String (id) title :: String (name, searchable) content :: WikiText (searchable) blog -> Blog created :: DateTime (default=now()) modified :: DateTime (default=now())}

Model

Page 25: Linguistic Abstraction for the Web

Automatic Persistence

Data Model

DB Schema

EntityClasses

WebDSLObject

JavaObject

DB Records

Page 26: Linguistic Abstraction for the Web

Logic

entity Blog { key :: String (id) title :: String (name) posts -> Set<Post> (inverse=Post.blog) function recentPosts(index: Int, n: Int): List<Post> { var i := max(1,index) - 1; return [p | p: Post in posts order by p.created desc limit n offset i*n].list(); } function newPost(): Post { var p := Post{ title := "No Title" blog := this }; p.key := p.id.toString(); return p; }}

Page 27: Linguistic Abstraction for the Web

View

Page 28: Linguistic Abstraction for the Web

Page Definition

define page blog(b: Blog, index: Int) { main(b){ for(p: Post in b.recentPosts(index,5)) { showPost(p) } } } define showPost(p: Post) { ... } define page post(p: Post) { ... }

Page 29: Linguistic Abstraction for the Web

define page blog(b: Blog, index: Int) { ... } define showPost(p: Post) { section{ header{ navigate post(p) { output(p.title) } } par{ output(p.content) } par{ output(p.created.format("MMMM d, yyyy")) } } } define page post(p: Post) { ... }

Navigate = Deferred Page Call

Template Definition

Page 30: Linguistic Abstraction for the Web

define page blog(b: Blog, index: Int) { ... } define showPost(p: Post) { ... } define page post(p: Post) { main(p.blog){ showPost(p) navigate editpost(p) { "[Edit]" } } }

Page Definition

Page 31: Linguistic Abstraction for the Web

Forms & Data Binding

define page post(p: Post) { ... } define page editpost(p: Post) { action save() { return post(p); } main(p.blog){ form{ formEntry("Title"){ input(p.title) } formEntry("Content") { input(p.content) } formEntry("Posted") { input(p.created) } submit save() { "Save" } } } }

(Look Ma, No Controller!)

Page 32: Linguistic Abstraction for the Web

Type-Directed Input

define page post(p: Post) { ... } define page editpost(p: Post) { action save() { return post(p); } main(p.blog){ form{ formEntry("Title"){ input(p.title) } formEntry("Content") { input(p.content) } formEntry("Posted") { input(p.created) } submit save() { "Save" } } } }

Page 33: Linguistic Abstraction for the Web

define sidebar(b: Blog) { list{ listitem{ navigate blog(b,1) { "Home" } } listitem{ submitlink action{ return editpost(b.newPost()); } { "[New Post]" } } } section{ header{"Recent Posts"} output(b.recentPosts(1,10)) } }

View Composition

Page 34: Linguistic Abstraction for the Web

define main(b: Blog) { includeCSS("style.css") <div id="outercontainer"> <div id="container"> <div id="sidebar">sidebar(b)</div> <div id="contents">elements</div> <div class="clear"> </div> </div> <div class="clear"> </div> </div> }

Native Interface

Page 35: Linguistic Abstraction for the Web

short demo: consistency checking

Integrated Development Environment

Page 36: Linguistic Abstraction for the Web

WebDSL Languages

Data Model

Logic

Templates (UI, Email, Service)

Access Control

Data Validation

Search

Collaborative Filtering

Page 37: Linguistic Abstraction for the Web

http://www.mobl-lang.org

Zef Hemel

Page 38: Linguistic Abstraction for the Web

Native Applications not Portable

Divergence in Mobile Platforms

Objective-C Java J2ME/C++

HTML/Javascript Java .NET

Page 39: Linguistic Abstraction for the Web

Convergence in Mobile Platform

Webkit browser

Webkit browser

Webkit browser

Webkit browser

Page 40: Linguistic Abstraction for the Web

The Universal Userinterface Engine

Page 41: Linguistic Abstraction for the Web

Mobile Web Architecture

Page 42: Linguistic Abstraction for the Web

Rich Applications

WebDatabases

Location information (GPS)

Canvas

Multi-touch

Offline support

Full-screen support

Accelerator support

Audio

Page 43: Linguistic Abstraction for the Web

Native Applications

Address book

Camera

Compass

File IO

Notifications

Page 44: Linguistic Abstraction for the Web

MVC, No Integration, No Abstraction, Accidental Complexity

Software Engineering with JavaScript

annotated HTML imperative Javascript

Page 45: Linguistic Abstraction for the Web

declarativetyped

integrated concise

Page 46: Linguistic Abstraction for the Web

Web Application with Touch

Page 47: Linguistic Abstraction for the Web

Portable Applications

Page 48: Linguistic Abstraction for the Web

Mobl Architecture

Page 49: Linguistic Abstraction for the Web

tipcalculator.mobl

application tipcalculator

import mobl::ui::generic

screen root() { var amount = 20 var percentage = 10 header("Tip calculator") group { item { numField(amount, label="amount") } item { numField(percentage, label="percentage") } item { "$" label(Math.round(amount * (1 + percentage/100))) } } nl()}

Page 50: Linguistic Abstraction for the Web

Task Manager

Page 51: Linguistic Abstraction for the Web

HTML5 Data Persistence

Data Model

entity Task { name : String (searchable) done : Bool due : DateTime category : Category (inverse: tasks) tags : Collection<Tag> (inverse: tasks)}entity Category { name : String tasks : Collection<Task> (inverse: category)}entity Tag { name : String tasks : Collection<Task> (inverse: tags)}

Page 52: Linguistic Abstraction for the Web

statically typed: catch errors early

Logic

entity Task { name : String (searchable) done : Bool due : DateTime category : Category (inverse: tasks) tags : Collection<Tag> (inverse: tasks) function postpone(days : Num) { this.due = DateTime.create( this.due.getFullYear(), this.due.getMonth(), this.due.getDate() + days); } function import(user : String, pw : String) { var tasksJSON = httpRequest("/export?user="+ user + "&pw=" + pw); foreach(t in tasksJSON) { add(Task.fromSelectJSON(t)); } }}

Page 53: Linguistic Abstraction for the Web

screen root() { var phrase = "" header("Tasks") { button("Add", onclick={ addTask(); }) } searchBox(phrase) group { list(t in Task.search(phrase) limit 20){ item { checkBox(t.done, label=t.name) } } }}

Reactive User Interfaces

Page 54: Linguistic Abstraction for the Web

screen root() { var phrase = "" header("Tasks") { button("Add", onclick={ addTask(); }) } searchBox(phrase) group { list(t in Task.search(phrase) limit 20){ item { checkBox(t.done, label=t.name) } } }}

Reactive User Interfaces

Page 55: Linguistic Abstraction for the Web

screen root() { var phrase = "" header("Tasks") { button("Add", onclick={ addTask(); }) } searchBox(phrase) group { list(t in Task.search(phrase) limit 20){ item { checkBox(t.done, label=t.name) } } }}

Navigation

Page 56: Linguistic Abstraction for the Web

screen root() { var phrase = "" header("Tasks") { button("Add", onclick={ addTask(); }) } searchBox(phrase) group { list(t in Task.search(phrase) limit 20){ item { checkBox(t.done, label=t.name) } } }}

screen addTask() { var t = Task() header("Add") { button("Done", onclick={ add(t); screen return; }) } textField(t.name) datePicker(t.due)}

Navigation

Page 57: Linguistic Abstraction for the Web

screen root() { var phrase = "" header("Tasks") { button("Add", onclick={ addTask(); }) } searchBox(phrase) group { list(t in Task.search(phrase) limit 20){ item { checkBox(t.done, label=t.name) } } }}

Navigation

Page 58: Linguistic Abstraction for the Web

Continuations

screen root() { button("Ask", onclick={ alert("Hello " + prompt("First name") + " " + prompt("Last name")); })}screen prompt(question : String) : String { var answer = "" header(question) { button("Done", onclick={ screen return answer; }) } textField(answer)}

Page 59: Linguistic Abstraction for the Web

User Interface Idiom: Tab

control tab1() { header("Tab 1") label("This is tab 1")}control tab2() { header("Tab 2") label("This is tab 2")}screen root() { tabSet([("One", tab1), ("Two", tab2)], defaultTab="One")}

Page 60: Linguistic Abstraction for the Web

increase coverage: developers can create abstractions

Tab Set: Higher-Order Control

control tabSet(tabs : [(String,Control)], activeTab : String) { list((tabName, tabControl) in tabs) { block(onclick={ activeTab = tabName; }, style=activeTab==tabName ? activeTabButton : inactiveTabButton) { label(tabName) } } list((tabName, tabControl) in tabs) { block(activeTab==tabName ? visibleTab : invisibleTab) { tabControl() } }}

Page 61: Linguistic Abstraction for the Web

User Interface Idiom: Master Detail

control taskItem(t : Task) { checkBox(t.done, label=t.name)}control taskDetail(t : Task) { textField(t.name) datePicker(t.due)}screen root() { header("Tasks") masterDetail(Task.all() order by due desc, taskItem, taskDetail)}

Page 62: Linguistic Abstraction for the Web

User Interface Idiom: Master Detail

control taskItem(t : Task) { checkBox(t.done, label=t.name)}control taskDetail(t : Task) { textField(t.name) datePicker(t.due)}screen root() { header("Tasks") masterDetail(Task.all() order by due desc, taskItem, taskDetail)}

Page 63: Linguistic Abstraction for the Web

Master Detail: Higher-Order Control

control masterDetail(items : Collection<?>, masterItem : Control1<?>, detail : Control1<?>) { group { list(it in items) { item(onclick={ detailScreen(it,detail); }) { masterItem(it) } } }}screen detailScreen(it : ?, detail : Control1<?>) { header("Detail") { backButton() } detail(it)}

Page 64: Linguistic Abstraction for the Web

Adaptive Layout

Page 65: Linguistic Abstraction for the Web

static cross-concern consistency checking

Mobl IDE

Page 66: Linguistic Abstraction for the Web

why do we need both?

Discussion

WebDSL vs Mobl

crucial difference: navigation models

Page 67: Linguistic Abstraction for the Web

http://researchr.org/search/publication/mobl+spoofax+webdsl

Linguistic Abstraction for the Web

http://spoofax.org

http://mobl-lang.org

http://webdsl.org

http://researchr.org

http://eelcovisser.org

separation of concerns + linguistic integration

cross concern consistency checking

early detection failures

Linguistic abstraction:capture software knowledge in

domain-specific languages

Language workbench: DSL design and implementation with less effort than

traditional language engineering