Your SlideShare is downloading. ×
mobl
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

mobl

978
views

Published on

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

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

Published in: Technology

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
978
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
10
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Slides from keynote at MOSE 2010, Malaga, June 29, 2010 Zef Hemel Eelco Visser @mobllang @zef @eelcovisser
  • 2. WebDSL Domain-Specific Language Engineering SDF Spoofax Stratego
  • 3. domain: mobile applications
  • 4. 50 million 20 million iPhones iPod Touches
  • 5. 1.5 million 1.2 million G1 Droid outsells iPhone in US
  • 6. application development
  • 7. Objective-C Java J2ME/C++ HTML/Javascript Java
  • 8. Objective-C Android Java Blackberry Java J2ME HTML/JS
  • 9. 3.3.1
  • 10. 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).
  • 11. AppStore
  • 12. cross-platform development arbitrary rejections we want high-level models
  • 13. Webkit
  • 14. HTML
  • 15. WebDatabases Full-screen support Location information (GPS) Offline support Canvas Multi-touch Threading
  • 16. “ 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
  • 17. syntax similar to
  • 18. data model user interface script web service access
  • 19. data model
  • 20. entity Task { name : String (searchable) done : Bool dueDate : DateTime }
  • 21. entity Task { name : String (searchable) done : Bool dueDate : DateTime categories : Collection<Category> } entity Category { name : String tasks : Collection<Task> (inverse: categories) }
  • 22. user interface
  • 23. screen root() { header("Todo") group { list(t in Task.all()) { item { checkbox(t.done) " " label(t.name) } } } }
  • 24. screen root() { header("Todo") topButton("Add", onclick={ addTask(); }) group { list(t in Task.all()) { item { checkbox(t.done) " " label(t.name) } } } }
  • 25. 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; }) }
  • 26. screen root() { header("Todo") topButton("Add", onclick={ addTask(); }) group { list(t in Task.all()) { item { checkbox(t.done) " " label(t.name) } } } }
  • 27. 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) } } } }
  • 28. scripting
  • 29. function cleanDoneTasks() : Num { var removed = 0; for(t in Task.all()) { if(t.done) { remove(t); removed = removed + 1; } } return removed; }
  • 30. data binding
  • 31. one-way var n = 0 label(n) button("Up", onclick={ n = n + 1; })
  • 32. two-way var n = 0 inputNum(n) label(n)
  • 33. reactive/dataflow programming
  • 34. var amount = 10 var percentage = 10 var total <- amount * (1 + percentage/100) inputNum(amount) inputNum(percentage) label(total)
  • 35. web services
  • 36. http://api.stackoverflow.com/0.8/questions?answers=true&body=true { "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": "...", ... }, ... ] }
  • 37. { "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> }
  • 38. { "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 ... }
  • 39. service StackOverflow { root = "http://api.stackoverflow.com/0.8" resource questions(answers : Bool, body : Bool) : QuestionsResultSet { uri = "/questions" method = "GET" encoding = "json" } ... }
  • 40. function fetchQuestions() { var res = StackOverflow.questions(answers=true, body=true); for(question : QuestionResult in res.questions) { mapQuestion(question); } }
  • 41. 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 }
  • 42. 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; }
  • 43. implementation
  • 44. mobl code parse check desugar generate code HTML/Javascript
  • 45. entity Task { name : String (searchable) done : Bool dueDate : DateTime } Javascript using persistence.js HTML5 ORM tasks.Task = persistence.define('tasks__Task', { 'name': 'TEXT', 'done': 'BOOL', 'dueDate': 'DATE' }); tasks.Task.textIndex('name');
  • 46. screen root() { header("Todo") ... } Javascript functions building DOM tasks.root = function(callback, screenCallback) { var root1018 = $("<div>"); mobl.header(ref("Todo"), function(node) { root1018.append(node); ... }); };
  • 47. 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; }
  • 48. 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; };
  • 49. 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 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); }); };
  • 50. reactive programming
  • 51. screen root() { var n = 8 label(n * n) button("Inc", onclick={ n = n + 1; }) }
  • 52. var n = 8 var n = ref(8); Observable - set(value) - get() - addEventListener(eventType, callback)
  • 53. 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);
  • 54. 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);
  • 55. screen root() { var n = 8 label(n * n) button("Inc", onclick={ n = n + 1; }) }
  • 56. conclusion
  • 57. many mobile platforms HTML5/JS avoid AppStore approval
  • 58. statically-typed WebDSL-like language generates HTML/JS CPS transform/reactive programming
  • 59. get it? http://mobl-lang.org http://spoofax.org