mobl

1,228 views

Published on

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
1,228
On SlideShare
0
From Embeds
0
Number of Embeds
325
Actions
Shares
0
Downloads
12
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

mobl

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

×