mobl

71
Eelco Visser Zef Hemel @mobllang @zef @eelcovisser Slides from keynote at MOSE 2010, Malaga, June 29, 2010

Upload: eelco-visser

Post on 15-May-2015

1.013 views

Category:

Technology


1 download

DESCRIPTION

slides from keynote for MOSE 2010 in Malaga on June 29, 2010

TRANSCRIPT

Page 1: mobl

Eelco VisserZef Hemel

@mobllang @zef @eelcovisser

Slides from keynote at MOSE 2010, Malaga, June 29, 2010

Page 2: mobl

Domain-Specific Language Engineering

WebDSL

SpoofaxSDF Stratego

Page 3: mobl

domain:mobile applications

Page 4: mobl

50 million

iPhones

20 million

iPod Touches

Page 5: mobl

1.5 million

G1

1.2 million

Droid

outsells iPhone in US

Page 6: mobl
Page 7: mobl

applicationdevelopment

Page 8: mobl

Objective-C Java J2ME/C++

HTML/Javascript Java

Page 9: mobl

Objective-C

Android Java

Blackberry Java

J2ME

HTML/JS

Page 10: mobl
Page 11: mobl

3.3.1

Page 12: mobl

3.3.1 – Applications may only use Documented APIs in the manner prescribed by Apple and must not use or call any private APIs. Applications must be originally written in Objective-C, C, C++, or JavaScript as executed by the iPhone OS WebKit engine, and only code written in C, C++, and Objective-C may compile and directly link against the Documented APIs (e.g., Applications that link to Documented APIs through an intermediary translation or compatibility layer or tool are prohibited).

Page 13: mobl
Page 14: mobl

AppStore

Page 15: mobl
Page 16: mobl

cross-platform development

arbitrary rejections

we want high-level models

Page 17: mobl
Page 18: mobl

Webkit

Page 19: mobl

HTML

Page 20: mobl

WebDatabases

Location information (GPS)

Threading

Canvas

WebDatabases

Multi-touch

Offline support

Full-screen support

Page 21: mobl
Page 22: mobl

We believe the web has won and over the next several years, the browser [..] will become the platform that matters and certainly that’s where Google is investing.

“ ”Vic Gundotra, Google VP of Engineering

Page 23: mobl
Page 24: mobl
Page 25: mobl

syntax similar to

Page 26: mobl

data model

user interface

script

web service access

Page 27: mobl

data model

Page 28: mobl

entity Task { name : String (searchable) done : Bool dueDate : DateTime}

Page 29: mobl

entity Task { name : String (searchable) done : Bool dueDate : DateTime categories : Collection<Category>}

entity Category { name : String tasks : Collection<Task> (inverse: categories)}

Page 30: mobl

user interface

Page 31: mobl

screen root() { header("Todo") group { list(t in Task.all()) { item { checkbox(t.done) " " label(t.name) } } }}

Page 32: mobl

screen root() { header("Todo") topButton("Add", onclick={ addTask(); }) group { list(t in Task.all()) { item { checkbox(t.done) " " label(t.name) } } }}

Page 33: mobl

screen addTask() { var newTask = Task { done = false, dueDate = now() }

header("Add") backButton("Back", onclick={ screen return; }) group { item { textField(newTask.name) } item { datePicker(newTask.dueDate) } } button("Add", onclick={ add(newTask); screen return; })}

Page 34: mobl

screen root() { header("Todo") topButton("Add", onclick={ addTask(); }) group { list(t in Task.all()) { item { checkbox(t.done) " " label(t.name) } } }}

Page 35: mobl

screen root() { var query = ""

header("Todo") topButton("Add", onclick={ addTask(); }) searchBox(query) group { list(t in Task.search(query)) { item { checkbox(t.done) " " label(t.name) } } }}

Page 36: mobl

scripting

Page 37: mobl

function cleanDoneTasks() : Num { var removed = 0; for(t in Task.all()) { if(t.done) { remove(t); removed = removed + 1; } } return removed;}

Page 38: mobl

data binding

Page 39: mobl

var n = 0

label(n)

button("Up", onclick={ n = n + 1;})

one-way

Page 40: mobl

var n = 0

inputNum(n)label(n)

two-way

Page 41: mobl

reactive/dataflow programming

Page 42: mobl
Page 43: mobl

var amount = 10var percentage = 10var total <- amount * (1 + percentage/100)

inputNum(amount)inputNum(percentage)label(total)

Page 44: mobl

web services

Page 45: mobl
Page 46: mobl
Page 47: mobl

{ "total": 746646, "page": 1, "pagesize": 30, "questions": [ { "tags": ["string", "assembly", "arm"], "answers": [], "question_id": 3092029, "owner": { "user_id": 320124, "user_type": "registered", "display_name": "SoulBeaver", "reputation": 195 }, "creation_date": 1277200629, "score": 0, "title": "ARM - Infinite Loop While Searching String", "body": "...", ... }, ... ]}

http://api.stackoverflow.com/0.8/questions?answers=true&body=true

Page 48: mobl

{ "total": 746646, "page": 1, "pagesize": 30, "questions": [ { "tags": ["string", "assembly", "arm"], "answers": [], "question_id": 3092029, "owner": { "user_id": 320124, "user_type": "registered", "display_name": "SoulBeaver", "reputation": 195 }, "creation_date": 1277200629, "score": 0, "title": "ARM - Infinite Loop While Searching String", "body": "...", ... }, ... ]}

external type QuestionsResultSet { total : Num page : Num pagesize : Num questions : Array<QuestionResult>}

Page 49: mobl

{ "tags": ["string", "assembly", "arm"], "answers": [], "question_id": 3092029, "owner": { "user_id": 320124, "user_type": "registered", "display_name": "SoulBeaver", "reputation": 195 }, "creation_date": 1277200629, "score": 0, "title": "ARM - Infinite Loop While Searching String", "body": "...", ...}

external type QuestionResult { tags : Array<String> answers : Array<AnswerResult> owner : OwnerResult creation_date : Num ...}

Page 50: mobl

service StackOverflow { root = "http://api.stackoverflow.com/0.8" resource questions(answers : Bool, body : Bool) : QuestionsResultSet { uri = "/questions" method = "GET" encoding = "json" } ...}

Page 51: mobl

function fetchQuestions() { var res = StackOverflow.questions(answers=true, body=true); for(question : QuestionResult in res.questions) { mapQuestion(question); }}

Page 52: mobl

entity Question { questionId : Num title : String body : Text answers : Collection<Answer> (inverse: question) creationDate : DateTime owner : User}

entity Answer { question : Question answerId : Num owner : User body : Text}

entity User { userId : Num name : String reputation : Num}

Page 53: mobl

function mapQuestion(qr : QuestionResult) : Question { var q : Question = cachedQuestion(remote.question_id); if(q == null) { q = Question { questionId = qr.question_id, title = qr.title, body = qr.body, answers = mapAnswers(qr.answers), creationDate = DateTime.fromTimestamp(qr.creation_date), owner = mapUser(qr.owner) }; add(q); } return q;}

Page 54: mobl
Page 55: mobl

implementation

Page 56: mobl

parse

check

desugar

generate code

mobl code

HTML/Javascript

Page 57: mobl

entity Task { name : String (searchable) done : Bool dueDate : DateTime}

tasks.Task = persistence.define('tasks__Task', { 'name': 'TEXT', 'done': 'BOOL', 'dueDate': 'DATE'});tasks.Task.textIndex('name');

Javascript usingpersistence.js

HTML5 ORM

Page 58: mobl

screen root() { header("Todo") ...}

tasks.root = function(callback, screenCallback) { var root1018 = $("<div>"); mobl.header(ref("Todo"), function(node) { root1018.append(node); ... });};

Javascript functions building DOM

Page 59: mobl

function cleanDoneTasks() : Num { var removed = 0; for(t in Task.all()) { if(t.done) { remove(t); removed = removed + 1; } } return removed;}

tasks.cleanDoneTasks = function() { var removed = 0; var results = Task.all(); for(var i = 0; i < results.length; i++) { var t = results[i]; if(t.done) { remove(t); removed = removed + 1; } } return removed;}

Page 60: mobl

function cleanDoneTasks() : Num { var removed = 0; for(t in Task.all()) { if(t.done) { remove(t); removed = removed + 1; } } return removed;}

tasks.cleanDoneTasks = function() { var removed = 0; var results = Task.all(); for(var i = 0; i < results.length; i++) { var t = results[i]; if(t.done) { remove(t); removed = removed + 1; } } return removed;};

Page 61: mobl

tasks.cleanDoneTasks = function(callback) { var removed = 0; Task.all(function(results) { for(var i = 0; i < results.length; i++) { var t = results[i]; if(t.done) { remove(t); removed = removed + 1; } } callback(removed); });};

tasks.cleanDoneTasks = function() { var removed = 0; var results = Task.all(); for(var i = 0; i < results.length; i++) { var t = results[i]; if(t.done) { remove(t); removed = removed + 1; } } return removed;};

continuation-passing style transform

Page 62: mobl

reactive programming

Page 63: mobl

screen root() { var n = 8 label(n * n) button("Inc", onclick={ n = n + 1; })}

Page 64: mobl

var n = 8

var n = ref(8);

Observable- set(value)- get()- addEventListener(eventType, callback)

Page 65: mobl

label(n * n)

var node565 = $("<span>");node565.text(n.get() * n.get());n.addEventListener("change", function() { node565.text(n.get() * n.get());});root.append(node565);

Page 66: mobl

button("Inc", onclick={ n = n + 1;})

var nodes566 = $("<span class='button'>");node566.text("Inc");node566.click(function() { n.set(n.get() + 1);});root.append(node566);

Page 67: mobl

screen root() { var n = 8 label(n * n) button("Inc", onclick={ n = n + 1; })}

Page 68: mobl

conclusion

Page 69: mobl

many mobile platforms

HTML5/JS

avoid AppStore approval

Page 70: mobl

statically-typed WebDSL-like language

generates HTML/JS

CPS transform/reactive programming