Zef Hemel, Eelco Visser
230,000/day
200,000/day
application
development
Objective-C
Objective-C Java
Objective-C Java J2ME/C++
Objective-C Java J2ME/C++
HTML/Javascript
Objective-C Java J2ME/C++
HTML/Javascript Java
Objective-C Java J2ME/C++
HTML/Javascript Java .NET
AppStore
portability
deployment
WWW
HTML
WebDatabases
WebDatabases
Location information
(GPS)
WebDatabases
Location information
(GPS)
Threading
WebDatabases
Location information
(GPS)
Threading
Canvas
WebDatabases
Location information
(GPS)
Threading
Canvas
Multi-touch
WebDatabases
Location information
(GPS)
Threading
Canvas
Multi-touch
Offline support
WebDatabases
Location information
(GPS)
Threading
Canvas
Multi-touch
Offline support
Full-screen support
mobile web apps
HTML
CSS
Javascript
SQL
cache
manifests
HTML
CSS
Javascript
SQL
cache
manifests
user interface abstraction
user interface abstraction
var results = tx.executeQuery("SELECT * FROM Task");
for(var i = 0; i < results.length; i++) {
alert(results[i].name);
}
s...
render page
query database
and process
results
...
time
render page
query database
and process
results
...
time
browser freeze
render page
send query
...
process query
result
...
time
tx.executeQuery("SELECT * FROM Task",
function(results) {
for(var i = 0; i < results.length; i++) {
alert(results[i].name)...
tx.executeQuery("SELECT * FROM Task",
function(results) {
alert("Hello, ");
});
alert("world!");
tx.executeQuery("SELECT * FROM Task",
function(results) {
tx.executeQuery("INSERT ...", function() {
alert("Selected, then...
mix of loosely-coupled DSLs
poor tool-support for mixed-language projects
lack of abstraction in UI
asynchronous programmi...
demo
http://confplan.zef.me
task 1:
user interface
http://mobl-lang.org/get.html
http://webdsl.org/zip/devnology/eclipselinux64.zip
http://webdsl.org/...
application tipcalculator
import mobl::ui::generic
screen root() {
var amount = 10
var percentage = 10
header("Tip calcula...
application tipcalculator
import mobl::ui::generic
screen root() {
var amount = 10
var percentage = 10
header("Tip calcula...
application tipcalculator
import mobl::ui::generic
screen root() {
var amount = 10
var percentage = 10
header("Tip calcula...
application tipcalculator
import mobl::ui::generic
screen root() {
var amount = 10
var percentage = 10
header("Tip calcula...
application tipcalculator
import mobl::ui::generic
screen root() {
var amount = 10
var percentage = 10
header("Tip calcula...
application tipcalculator
import mobl::ui::generic
screen root() {
var amount = 10
var percentage = 10
header("Tip calcula...
task 2:
scripting
application test
import mobl::ui::generic
function fac(n : Num) : Num {
if(n == 1) {
return 1;
} else {
return n * fac(n-1...
application test
import mobl::ui::generic
function fac(n : Num) : Num {
if(n == 1) {
return 1;
} else {
return n * fac(n-1...
application test
import mobl::ui::generic
function fac(n : Num) : Num {
if(n == 1) {
return 1;
} else {
return n * fac(n-1...
application todo
import mobl::ui::generic
function fac(n : Num) : Num {
if(n == 1) {
return 1;
} else {
return n * fac(n-1...
application test
import mobl::ui::generic
function fac(n : Num) : Num {
if(n == 1) {
return 1;
} else {
return n * fac(n-1...
var pos = getPosition();
alert("Your location is: " + pos);
var pos = getPosition();
alert("Your location is: " + pos);
var pos;
getPosition(function(result) {
pos = result;
alert("Y...
task 3:
data modeling and query
entity Task {
name : String (searchable)
done : Bool
dateAdded : DateTime
}
entity Task {
name : String (searchable)
done : Bool
dateAdded : DateTime
category : Category (inverse: tasks)
tags : Coll...
screen root() {
header("Tasks") {
button("Add", onclick={ addTask(); })
}
group {
list(t in Task.all() order by dateAdded ...
screen root() {
header("Tasks") {
button("Add", onclick={ addTask(); })
}
group {
list(t in Task.all() order by dateAdded ...
control taskItem(t : Task) {
item(onclick={ taskDetails(t); }) {
checkBox(t.done)
" "
label(t.name)
contextMenu {
button("...
control taskItem(t : Task) {
item(onclick={ taskDetails(t); }) {
checkBox(t.done)
" "
label(t.name)
contextMenu {
button("...
Task.all()
Task.all() where done == false && ...
order by dateAdded desc
limit 10
offset 5
Task.all() where done == false && ...
order by dateAdded desc
limit 10
offset 5
task 4:
higher-order controls and
native interfaces
control taskItem(t : Task) {
checkBox(t.done)
" "
label(t.name)
contextMenu {
button("Remove", onclick={
remove(t);
})
}
}...
control taskItem(t : Task) {
checkBox(t.done)
" "
label(t.name)
contextMenu {
button("Remove", onclick={
remove(t);
})
}
}...
control masterDetail(items : Collection<Dynamic>, masterItem : Control1<Dynamic>,
detail : Control1<Dynamic>) {
group {
li...
external type LocalStorage {
static sync function getItem(key : String) : Dynamic
static sync function setItem(key : Strin...
what else is there?
service DataProvider {
resource getNearbyConferences(lat : Num, long : Num) : [JSON] {
uri = "/nearbyConferences"
}
resour...
service DataProvider {
resource getNearbyConferences(lat : Num, long : Num) : [JSON] {
uri = "/nearbyConferences"
}
resour...
location & maps
mobl::ui::ios mobl::ui::jq
mobl::ui::ios mobl::ui::jq
mobl::ui
application confplan
offline true
title "ConfPlan"
future
adaptive user interfaces
database sync
more high-level controls
web/native hybrid (PhoneGap)
http://mobl-lang.org
http://twitter.com/zef
http://twitter.com/mobllang
http://zef.me
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
Upcoming SlideShare
Loading in...5
×

mobl: Een DSL voor mobiele applicatieontwikkeling

364

Published on

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
364
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

mobl: Een DSL voor mobiele applicatieontwikkeling

  1. 1. Zef Hemel, Eelco Visser
  2. 2. 230,000/day
  3. 3. 200,000/day
  4. 4. application development
  5. 5. Objective-C
  6. 6. Objective-C Java
  7. 7. Objective-C Java J2ME/C++
  8. 8. Objective-C Java J2ME/C++ HTML/Javascript
  9. 9. Objective-C Java J2ME/C++ HTML/Javascript Java
  10. 10. Objective-C Java J2ME/C++ HTML/Javascript Java .NET
  11. 11. AppStore
  12. 12. portability deployment
  13. 13. WWW
  14. 14. HTML
  15. 15. WebDatabases
  16. 16. WebDatabases Location information (GPS)
  17. 17. WebDatabases Location information (GPS) Threading
  18. 18. WebDatabases Location information (GPS) Threading Canvas
  19. 19. WebDatabases Location information (GPS) Threading Canvas Multi-touch
  20. 20. WebDatabases Location information (GPS) Threading Canvas Multi-touch Offline support
  21. 21. WebDatabases Location information (GPS) Threading Canvas Multi-touch Offline support Full-screen support
  22. 22. mobile web apps
  23. 23. HTML CSS Javascript SQL cache manifests
  24. 24. HTML CSS Javascript SQL cache manifests
  25. 25. user interface abstraction
  26. 26. user interface abstraction
  27. 27. var results = tx.executeQuery("SELECT * FROM Task"); for(var i = 0; i < results.length; i++) { alert(results[i].name); } synchronous programming
  28. 28. render page query database and process results ... time
  29. 29. render page query database and process results ... time browser freeze
  30. 30. render page send query ... process query result ... time
  31. 31. tx.executeQuery("SELECT * FROM Task", function(results) { for(var i = 0; i < results.length; i++) { alert(results[i].name); } }); ... asynchronous programming
  32. 32. tx.executeQuery("SELECT * FROM Task", function(results) { alert("Hello, "); }); alert("world!");
  33. 33. tx.executeQuery("SELECT * FROM Task", function(results) { tx.executeQuery("INSERT ...", function() { alert("Selected, then inserted"); }); });
  34. 34. mix of loosely-coupled DSLs poor tool-support for mixed-language projects lack of abstraction in UI asynchronous programming
  35. 35. demo http://confplan.zef.me
  36. 36. task 1: user interface http://mobl-lang.org/get.html http://webdsl.org/zip/devnology/eclipselinux64.zip http://webdsl.org/zip/devnology/eclipselinux.zip http://webdsl.org/zip/devnology/eclipsemac64.zip http://webdsl.org/zip/devnology/eclipsewin.zip
  37. 37. application tipcalculator import mobl::ui::generic screen root() { var amount = 10 var percentage = 10 header("Tip calculator") group { item { numField(amount, label="amount") } item { numField(percentage, label="percentage") } item { "$" label(amount * (1 + percentage/100)) } } }
  38. 38. application tipcalculator import mobl::ui::generic screen root() { var amount = 10 var percentage = 10 header("Tip calculator") group { item { numField(amount, label="amount") } item { numField(percentage, label="percentage") } item { "$" label(amount * (1 + percentage/100)) } } }
  39. 39. application tipcalculator import mobl::ui::generic screen root() { var amount = 10 var percentage = 10 header("Tip calculator") group { item { numField(amount, label="amount") } item { numField(percentage, label="percentage") } item { "$" label(amount * (1 + percentage/100)) } } }
  40. 40. application tipcalculator import mobl::ui::generic screen root() { var amount = 10 var percentage = 10 header("Tip calculator") group { item { numField(amount, label="amount") } item { numField(percentage, label="percentage") } item { "$" label(amount * (1 + percentage/100)) } } }
  41. 41. application tipcalculator import mobl::ui::generic screen root() { var amount = 10 var percentage = 10 header("Tip calculator") group { item { numField(amount, label="amount") } item { numField(percentage, label="percentage") } item { "$" label(amount * (1 + percentage/100)) } } }
  42. 42. application tipcalculator import mobl::ui::generic screen root() { var amount = 10 var percentage = 10 header("Tip calculator") group { item { numField(amount, label="amount") } item { numField(percentage, label="percentage") } item { "$" label(amount * (1 + percentage/100)) } } }
  43. 43. task 2: scripting
  44. 44. application test import mobl::ui::generic function fac(n : Num) : Num { if(n == 1) { return 1; } else { return n * fac(n-1); } } screen promptNum(question : String) : Num { var answer = 0 header(question) { button("Done", onclick={ screen return answer; }) } group { item { numField(answer) } } } screen root() { header("Calculator") var n = 2 group { item { numField(n) } } button("*", onclick={ n = n * promptNum("Multiply with"); }) button("+", onclick={ n = n + promptNum("Add"); }) button("!", onclick={ n = fac(n); }) }
  45. 45. application test import mobl::ui::generic function fac(n : Num) : Num { if(n == 1) { return 1; } else { return n * fac(n-1); } } screen promptNum(question : String) : Num { var answer = 0 header(question) { button("Done", onclick={ screen return answer; }) } group { item { numField(answer) } } } screen root() { header("Calculator") var n = 2 group { item { numField(n) } } button("*", onclick={ n = n * promptNum("Multiply with"); }) button("+", onclick={ n = n + promptNum("Add"); }) button("!", onclick={ n = fac(n); }) }
  46. 46. application test import mobl::ui::generic function fac(n : Num) : Num { if(n == 1) { return 1; } else { return n * fac(n-1); } } screen promptNum(question : String) : Num { var answer = 0 header(question) { button("Done", onclick={ screen return answer; }) } group { item { numField(answer) } } } screen root() { header("Calculator") var n = 2 group { item { numField(n) } } button("*", onclick={ n = n * promptNum("Multiply with"); }) button("+", onclick={ n = n + promptNum("Add"); }) button("!", onclick={ n = fac(n); }) }
  47. 47. application todo import mobl::ui::generic function fac(n : Num) : Num { if(n == 1) { return 1; } else { return n * fac(n-1); } } screen promptNum(question : String) : Num { var answer = 0 header(question) { button("Done", onclick={ screen return answer; }) } group { item { numField(answer) } } } screen root() { header("Calculator") var n = 2 group { item { numField(n) } } button("*", onclick={ n = n * promptNum("Multiply with"); }) button("+", onclick={ n = n + promptNum("Add"); }) button("!", onclick={ n = fac(n); }) }
  48. 48. application test import mobl::ui::generic function fac(n : Num) : Num { if(n == 1) { return 1; } else { return n * fac(n-1); } } screen promptNum(question : String) : Num { var answer = 0 header(question) { button("Done", onclick={ screen return answer; }) } group { item { numField(answer) } } } screen root() { header("Calculator") var n = 2 group { item { numField(n) } } button("*", onclick={ n = n * promptNum("Multiply with"); }) button("+", onclick={ n = n + promptNum("Add"); }) button("!", onclick={ n = fac(n); }) }
  49. 49. var pos = getPosition(); alert("Your location is: " + pos);
  50. 50. var pos = getPosition(); alert("Your location is: " + pos); var pos; getPosition(function(result) { pos = result; alert("Your location is: " + pos); ... }); continuation-passing style transformation
  51. 51. task 3: data modeling and query
  52. 52. entity Task { name : String (searchable) done : Bool dateAdded : DateTime }
  53. 53. entity Task { name : String (searchable) done : Bool dateAdded : 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) }
  54. 54. screen root() { header("Tasks") { button("Add", onclick={ addTask(); }) } group { list(t in Task.all() order by dateAdded desc) { taskItem(t) } } button("Search", onclick={ search(); }) } screen search() { var phrase = "" header("Search") { backButton() } searchBox(phrase) group { list(t in Task.searchPrefix(phrase)) { taskItem(t) } } }
  55. 55. screen root() { header("Tasks") { button("Add", onclick={ addTask(); }) } group { list(t in Task.all() order by dateAdded desc) { taskItem(t) } } button("Search", onclick={ search(); }) } screen search() { var phrase = "" header("Search") { backButton() } searchBox(phrase) group { list(t in Task.searchPrefix(phrase)) { taskItem(t) } } }
  56. 56. control taskItem(t : Task) { item(onclick={ taskDetails(t); }) { checkBox(t.done) " " label(t.name) contextMenu { button("Remove", onclick={ remove(t); }) } } }
  57. 57. control taskItem(t : Task) { item(onclick={ taskDetails(t); }) { checkBox(t.done) " " label(t.name) contextMenu { button("Remove", onclick={ remove(t); }) } } }
  58. 58. Task.all()
  59. 59. Task.all() where done == false && ... order by dateAdded desc limit 10 offset 5
  60. 60. Task.all() where done == false && ... order by dateAdded desc limit 10 offset 5
  61. 61. task 4: higher-order controls and native interfaces
  62. 62. control taskItem(t : Task) { checkBox(t.done) " " label(t.name) contextMenu { button("Remove", onclick={ remove(t); }) } } control taskDetail(t : Task) { group { item { textField(t.name, placeholder="Task name") } item { checkBox(t.done, label="Done") } } } screen root() { header("Tasks") { button("Add", onclick={ addTask(); }) } masterDetail(Task.all() order by dateAdded desc, taskItem, taskDetail) button("Search", onclick={ search(); }) }
  63. 63. control taskItem(t : Task) { checkBox(t.done) " " label(t.name) contextMenu { button("Remove", onclick={ remove(t); }) } } control taskDetail(t : Task) { group { item { textField(t.name, placeholder="Task name") } item { checkBox(t.done, label="Done") } } } screen root() { header("Tasks") { button("Add", onclick={ addTask(); }) } masterDetail(Task.all() order by dateAdded desc, taskItem, taskDetail) button("Search", onclick={ search(); }) }
  64. 64. control masterDetail(items : Collection<Dynamic>, masterItem : Control1<Dynamic>, detail : Control1<Dynamic>) { group { list(it in items) { item(onclick={ detailScreen(it, detail); }) { masterItem(it) } } } } screen detailScreen(it : Dynamic, detail : Control1<Dynamic>) { header("Detail") { backButton("Back", onclick={ screen return; }) } detail(it) }
  65. 65. external type LocalStorage { static sync function getItem(key : String) : Dynamic static sync function setItem(key : String, val : Object) : void static sync function removeItem(key : String) : void static sync function clear() : void } <javascript> firstapp.LocalStorage = window.localStorage; </javascript>
  66. 66. what else is there?
  67. 67. service DataProvider { resource getNearbyConferences(lat : Num, long : Num) : [JSON] { uri = "/nearbyConferences" } resource fetchProgram(conferenceId : String) : [JSON] { uri = "/conferenceProgram" } } web services
  68. 68. service DataProvider { resource getNearbyConferences(lat : Num, long : Num) : [JSON] { uri = "/nearbyConferences" } resource fetchProgram(conferenceId : String) : [JSON] { uri = "/conferenceProgram" } } function loadLocalConferences() { var position = getPosition(); var nearbyConferencesJson = DataProvider.getNearbyConferences(position.latitude, position.longitude); foreach(jsonObj in nearbyConferencesJson) { Conference.fromSelectJson(jsonObj); } } web services
  69. 69. location & maps
  70. 70. mobl::ui::ios mobl::ui::jq
  71. 71. mobl::ui::ios mobl::ui::jq mobl::ui
  72. 72. application confplan offline true title "ConfPlan"
  73. 73. future
  74. 74. adaptive user interfaces database sync more high-level controls web/native hybrid (PhoneGap)
  75. 75. http://mobl-lang.org http://twitter.com/zef http://twitter.com/mobllang http://zef.me
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×