mobl
DESCRIPTION
slides from keynote for MOSE 2010 in Malaga on June 29, 2010TRANSCRIPT
![Page 1: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/1.jpg)
Eelco VisserZef Hemel
@mobllang @zef @eelcovisser
Slides from keynote at MOSE 2010, Malaga, June 29, 2010
![Page 2: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/2.jpg)
Domain-Specific Language Engineering
WebDSL
SpoofaxSDF Stratego
![Page 3: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/3.jpg)
domain:mobile applications
![Page 4: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/4.jpg)
50 million
iPhones
20 million
iPod Touches
![Page 5: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/5.jpg)
1.5 million
G1
1.2 million
Droid
outsells iPhone in US
![Page 6: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/6.jpg)
![Page 7: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/7.jpg)
applicationdevelopment
![Page 8: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/8.jpg)
Objective-C Java J2ME/C++
HTML/Javascript Java
![Page 9: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/9.jpg)
Objective-C
Android Java
Blackberry Java
J2ME
HTML/JS
![Page 10: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/10.jpg)
![Page 11: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/11.jpg)
3.3.1
![Page 12: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/12.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/13.jpg)
![Page 14: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/14.jpg)
AppStore
![Page 15: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/15.jpg)
![Page 16: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/16.jpg)
cross-platform development
arbitrary rejections
we want high-level models
![Page 17: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/17.jpg)
![Page 18: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/18.jpg)
Webkit
![Page 19: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/19.jpg)
HTML
![Page 20: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/20.jpg)
WebDatabases
Location information (GPS)
Threading
Canvas
WebDatabases
Multi-touch
Offline support
Full-screen support
![Page 21: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/21.jpg)
![Page 22: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/22.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/23.jpg)
![Page 24: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/24.jpg)
![Page 25: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/25.jpg)
syntax similar to
![Page 26: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/26.jpg)
data model
user interface
script
web service access
![Page 27: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/27.jpg)
data model
![Page 28: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/28.jpg)
entity Task { name : String (searchable) done : Bool dueDate : DateTime}
![Page 29: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/29.jpg)
entity Task { name : String (searchable) done : Bool dueDate : DateTime categories : Collection<Category>}
entity Category { name : String tasks : Collection<Task> (inverse: categories)}
![Page 30: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/30.jpg)
user interface
![Page 31: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/31.jpg)
screen root() { header("Todo") group { list(t in Task.all()) { item { checkbox(t.done) " " label(t.name) } } }}
![Page 32: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/32.jpg)
screen root() { header("Todo") topButton("Add", onclick={ addTask(); }) group { list(t in Task.all()) { item { checkbox(t.done) " " label(t.name) } } }}
![Page 33: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/33.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/34.jpg)
screen root() { header("Todo") topButton("Add", onclick={ addTask(); }) group { list(t in Task.all()) { item { checkbox(t.done) " " label(t.name) } } }}
![Page 35: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/35.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/36.jpg)
scripting
![Page 37: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/37.jpg)
function cleanDoneTasks() : Num { var removed = 0; for(t in Task.all()) { if(t.done) { remove(t); removed = removed + 1; } } return removed;}
![Page 38: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/38.jpg)
data binding
![Page 39: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/39.jpg)
var n = 0
label(n)
button("Up", onclick={ n = n + 1;})
one-way
![Page 40: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/40.jpg)
var n = 0
inputNum(n)label(n)
two-way
![Page 41: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/41.jpg)
reactive/dataflow programming
![Page 42: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/42.jpg)
![Page 43: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/43.jpg)
var amount = 10var percentage = 10var total <- amount * (1 + percentage/100)
inputNum(amount)inputNum(percentage)label(total)
![Page 44: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/44.jpg)
web services
![Page 45: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/45.jpg)
![Page 46: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/46.jpg)
![Page 47: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/47.jpg)
{ "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](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/48.jpg)
{ "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](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/49.jpg)
{ "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](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/50.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/51.jpg)
function fetchQuestions() { var res = StackOverflow.questions(answers=true, body=true); for(question : QuestionResult in res.questions) { mapQuestion(question); }}
![Page 52: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/52.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/53.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/54.jpg)
![Page 55: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/55.jpg)
implementation
![Page 56: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/56.jpg)
parse
check
desugar
generate code
mobl code
HTML/Javascript
![Page 57: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/57.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/58.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/59.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/60.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/61.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/62.jpg)
reactive programming
![Page 63: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/63.jpg)
screen root() { var n = 8 label(n * n) button("Inc", onclick={ n = n + 1; })}
![Page 64: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/64.jpg)
var n = 8
var n = ref(8);
Observable- set(value)- get()- addEventListener(eventType, callback)
![Page 65: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/65.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/66.jpg)
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](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/67.jpg)
screen root() { var n = 8 label(n * n) button("Inc", onclick={ n = n + 1; })}
![Page 68: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/68.jpg)
conclusion
![Page 69: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/69.jpg)
many mobile platforms
HTML5/JS
avoid AppStore approval
![Page 70: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/70.jpg)
statically-typed WebDSL-like language
generates HTML/JS
CPS transform/reactive programming
![Page 71: mobl](https://reader034.vdocument.in/reader034/viewer/2022052619/5555a697d8b42a52568b470b/html5/thumbnails/71.jpg)
get it?
http://mobl-lang.org
http://spoofax.org