Upload
zefhemel
View
2.383
Download
0
Tags:
Embed Size (px)
Citation preview
230,000 300,000
Objective-C Java J2ME/C++
HTML/Javascript Java .NET
portability
Objective-C Java J2ME/C++
HTML/Javascript Java .NET
Webkit browser Webkit browser J2ME/C++
Webkit browser Webkit browser .NET
WebDatabases
WebDatabases
Location information (GPS)
WebDatabases
Location information (GPS)
Canvas
WebDatabases
Location information (GPS)
Canvas
Multi-touch
WebDatabases
Location information (GPS)
Canvas
Multi-touch
Offline support
WebDatabases
Location information (GPS)
Canvas
Multi-touch
Offline support
Full-screen support
WebDatabases
Location information (GPS)
Canvas
Multi-touch
Offline support
Full-screen support
Accelerator support
Address book
Address book
Camera
Address book
Camera
Compass
Address book
Camera
Compass
File IO
Address book
Camera
Compass
File IO
Audio
Address book
Camera
Compass
File IO
Audio
Notifications
mobl program
1. language
2. behind the scenes
today
language
user interface
styling
data modeling
scripting
web services
user interface
demo
screen name(farg*) : ReturnType? { screenelem*}
control name(farg*) { screenelem*}
ui syntax
screen root() { ...}
screen root() { ...}
screen promptString(q : String) : String { ...}
screen root() { ...}
screen promptString(q : String) : String { ...}
control button(s : String, onclick : Callback = {}) { ...}
control calls
variable declarations
inline HTML
script blocks
control structures
button("Click me")
control calls
button("Click me")
button("Click me", { alert("Click!");})
control calls
button("Click me")
button("Click me", { alert("Click!");})
button("Click me", onclick={ alert("Click!");})
control calls
group() { item() { "Item 1" } item() { "Item 2" }}
control calls with body
group { item { "Item 1" } item { "Item 2" }}
control calls with body
variable declarations
var b = true
variable declarations
var b = truevar b : Bool = true
variable declarations
var b = true
var newTask = Task()
var b : Bool = true
variable declarations
var b = true
var newTask = Task()
var b : Bool = true
var newTask : Task = Task()
when
var b = true
checkBox(b)
when(b) { label("Yep")} else { label("Nope")}
list
var nums = [1, 2, 3]
group { list(n in nums) { item { label(n) } }}
inline HTML
<img src="img/icon.png"/>
inline HTML
<img src="img/icon.png"/>
<div class=selected ? selectedStyle : notSelectedStyle> ...</div>
script blocks
var n = -1script { n = Math.sqrt(9);}
avoid if possible
higher-order controls
demo
styling
style bigAndBlue { color: blue; font-size: 40px;}
style bigAndBlue { color: blue; font-size: 40px;}
Style
control block(style : Style) { ...}
block(bigAndBlueStyle) { label("I am big and blue!");}
style $baseColor = rgb(100, 100, 100)
style myStyle { color: rgb($baseColor.r+10, $baseColor.g+50, $baseColor.b-20); font-size: 20px;}
style mixin borderRadiusMixin($radius) { -moz-border-radius: $radius; -webkit-border-radius: $radius; border-radius: $radius;}
style mixin borderRadiusMixin($radius) { -moz-border-radius: $radius; -webkit-border-radius: $radius; border-radius: $radius;}
style myStyle { color: $baseColor; borderRadiusMixin(10px);}
demo
data modeling& query
entity Task { name : String (searchable) done : Bool tags : Collection<Tag> (inverse: tasks)}
entity Tag { name : String (searchable) tasks : Collection<Task> (inverse: tags)}
var newTask = Task(name="New task");newTask.done = false;add(newTask);
var doneTasks = Task.all()
var doneTasks = Task.all()
Collection<Task>
var doneTasks = Task.all()
Collection<Task>
.filter("done", "=", true)
.order("date", false)
.limit(10);
var tagDoneTasks = tag.tasks .filter("done", "=", true) .order("date", false) .limit(10);
Collection<Task>
var doneTasks = Task.all()
Collection<Task>
var doneTasks = Task.all()
Collection<Task>
where done == trueorder by date desclimit 10;
var tagDoneTasks = tag.tasks where done == true order by date desc limit 10;
Collection<Task>
var searchTasks = Task.search("task") where done == true limit 10;
Collection<Task>
screen root() { header("Tasks") group { list(t in Task.all() order by date desc) { item { label(t.name) } } }}
scripting
label("Total tasks: " + Task.all().count())
script in ui
button("Click me", onclick={ alert("You clicked me!");})
label("Total tasks: " + Task.all().count())
script in ui
var n = 7;var n2 = Math.round(n/2);
if(n2 > 3) { alert("More than three!");} else { alert("Less than three!");}
var n = 7;var n2 = Math.round(n/2);
if(n2 > 3) { alert("More than three!");} else { alert("Less than three!");}
type inference
var done = 0;foreach(t in Task.all()) { if(t.done) { done = done + 1; }}
var done = 0;foreach(t in Task.all()) { if(t.done) { done = done + 1; }}
var done = (Task.all() where done == true) .count();
function sqr(n : Num) : Num { return n * n;}
demo: todo list
web serviceaccess
service SomeService { resource tasks() : JSON { uri = "/tasks" }
resource search(query : String) : JSON { uri = "/search?q=" + escape(query) }}
service Twitter { resource trends() : JSON { uri = "/_proxy/api.twitter.com/1/trends.json" }
resource search(query : String) : JSON { uri = "/_proxy/search.twitter.com/search.json?q=" + escape(query) }}
ajax same-source restriction
{"trends": [{"url":"http:\/\/search.twitter.com\/search?q=...", "name":"#ihaveadream"}, {"url":"http:\/\/search.twitter.com\/search?q=...", "name":"#mlkday"} ... ]}
http://api.twitter.com/1/trends.json
type Trend { name : String url : String}
function trendsMapper(json : JSON) : [Trend] { return json.trends;}
resource trends() : JSON { uri = "/_proxy/api.twitter.com/1/trends.json" mapper = trendsMapper}
screen root() { var trends = Twitter.trends()
header("Twitter trends") group { list(topic in trends) { item { label(topic.name) } } }}
user interface
styling
data modeling
scripting
web services
slower than native
no native UI
not great for games
limitations
behind the scenes
goals
coverage
portability
completeness
goals
coverage
portability
completeness
web
goals
coverage
portability
completeness 100% code gen
web
design bottom-up
1. design core abstractions + native interface
roadmap
1. design core abstractions + native interface
2. enable user land abstractions
roadmap
1. design core abstractions + native interface
2. enable user land abstractions
3a. support successful ULAs with syntax
roadmap
1. design core abstractions + native interface
2. enable user land abstractions
3a. support successful ULAs with syntax
3b. support common native interface cases with core abstractions
roadmap
1. design core abstractions + native interface
2. enable user land abstractions
3a. support successful ULAs with syntax
3b. support common native interface cases with core abstractions
roadmap
synchronous programming
core abstraction:
no more asynchronous spaghetti code
var results = Task.all().list();for(var i = 0; i < results.length; i++) { alert(results[i].name);}
synchronous programming
render page
query database and process
results
...
time
render page
query database and process
results
...
timebrowser freeze
render page
send query
...
process query result
...
time
Task.all.list(function(results) { for(var i = 0; i < results.length; i++) { alert(results[i].name); } });...
asynchronous programming
Task.all().list(function(results) { alert("Hello, "); });alert("world!");
Task.all().list(function(results) { alert("Hello, "); });alert("world!");
breaks sequential execution assumption
Task.all().list(function(results) { // make changes ... persistence.flush(function() { alert("Changes saved!"); });});
continuation-passing styletransformation
function displayLocationAndReturn() : Coordinates { var position = mobl::location::getPosition(); log("Lat: " + position.latitude); log("Long: " + position.longitude); return position;}
function displayLocationAndReturn() : Coordinates { var position = mobl::location::getPosition(); log("Lat: " + position.latitude); log("Long: " + position.longitude); return position;}
function displayLocationAndReturn(callback) { mobl.location.getPosition(function(position) { console.log("Lat: " + position.latitude); console.log("Long: " + position.longitude); callback(position); });};
function displayLocationAndReturn() : Coordinates { var position = mobl::location::getPosition(); log("Lat: " + position.latitude); log("Long: " + position.longitude); return position;}
function displayLocationAndReturn(callback) { mobl.location.getPosition(function(position) { console.log("Lat: " + position.latitude); console.log("Long: " + position.longitude); callback(position); });};
function displayLocationAndReturn() : Coordinates { var position = mobl::location::getPosition(); log("Lat: " + position.latitude); log("Long: " + position.longitude); return position;}
function displayLocationAndReturn(callback) { mobl.location.getPosition(function(position) { console.log("Lat: " + position.latitude); console.log("Long: " + position.longitude); callback(position); });};
data bindingcore abstraction:
no more copying data from and to UI
screen root() { var n = 8 label(n * n) button("Inc", onclick={ n = n + 1; })}
var n = 8
var n = ref(8);
var n = 8
var n = ref(8);
Observable- set(value)- get()- addEventListener(eventType, callback)
label(n * n)
var node = $("<span>");node.text(n.get() * n.get());n.addEventListener("change", function() { node.text(n.get() * n.get());});root.append(node);
label(n * n)
var node = $("<span>");node.text(n.get() * n.get());n.addEventListener("change", function() { node.text(n.get() * n.get());});root.append(node);
label(n * n)
var node = $("<span>");node.text(n.get() * n.get());n.addEventListener("change", function() { node.text(n.get() * n.get());});root.append(node);
button("Inc", onclick={ n = n + 1;})
var node = $("<button ...>");node.text("Inc");node.click(function() { n.set(n.get() + 1);});root.append(node);
button("Inc", onclick={ n = n + 1;})
var node = $("<button ...>");node.text("Inc");node.click(function() { n.set(n.get() + 1);});root.append(node);
screen root() { var n = 8 label(n * n) button("Inc", onclick={ n = n + 1; })}
screen root() { var n = 8 label(n * n) button("Inc", onclick={ n = n + 1; })}
screen root() { var n = 8 label(n * n) button("Inc", onclick={ n = n + 1; })}
data modeling & query
core abstraction:
no more SQL
entity Task { name : String (searchable) description : String (searchable) done : Bool date : DateTime}
var Task = persistence.define('Task', { name: 'VARCHAR(255)', description: 'VARCHAR(255)', done: 'BOOL', date: 'DATE'});
Task.textIndex('description');Task.textIndex('name');
foreach(t in Task.all()) { alert(t.name);}
Task.all().forEach(function(t) { alert(t.name);});
foreach(t in Task.all() where done == true) { alert(t.name);}
Task.all().filter("done", "=", true).forEach(function(t) { alert(t.name);});
native interface
external entity MyEntity
external control contextMenu()
external screen specialScreen()
external sync function add(o : Object) : void
external style myStyle
external type MyType
external sync function add(o : Object) : void
<javascript>__ns.add = function(o) { persistence.add(o);};</javascript>
load styles/default.cssload js/persistence.js
where do abstractions come from?
where do abstractions come from?
domain
where do abstractions come from?
domain
experience
domain
domain
screen
domain
screen
control
domain
screen
control
entity
domain
screen
control
entity
event
domain
screen
control
entity
event web service
experience
experience
other DSLs
experience
programming paradigms
other DSLs
experience
programming paradigms
annoyancesother DSLs
1. design core abstractions + native interface
2. enable user land abstractions
3a. support successful ULAs with syntax
3b. support common native interface cases with core abstractions
roadmap
goal
compiler small
library large (and extensible)
how?
- built-in types- built-in controls
+ native interface+ sufficiently low-level primitives+ abstraction mechanisms (screens, controls, functions, types)
native interfaceexternal type Object { sync function toString() : String}
external type String : Object { length : Num sync function charAt(index : Num) : String sync function charCodeAt(index : Num) : Num ...}
external type Num : Object { }external type Bool : Object { }external type Dynamic : Object { }external type Style : String { }
external type Array<T> { length : Num
sync function get(n : Num) : T sync function push(item : T) : void sync function join(sep : String) : String ...}
control image(url : String, onclick : Callback = null) { <img src=url onclick=onclick/>}
low-level primitives
control slideupBlock() { div@<div onclick={ div.slideUp(); }> elements() </div>}
...
slideupBlock { label("Click me to slide up")}
low-level primitives
control slideupBlock() { div@<div onclick={ div.slideUp(); }> elements() </div>}
...
slideupBlock { label("Click me to slide up")}
low-level primitives
JQuery
1. design core abstractions + native interface
2. enable user land abstractions
3a. support successful ULAs with syntax
3b. support common native interface cases with core abstractions
roadmap
var doneTasks = Task.all()
var doneTasks = Task.all().filter("done", "=", true).order("date", false).limit(10);
var doneTasks = Task.all()
var doneTasks = Task.all()where done == trueorder by date desclimit 10;
1. design core abstractions + native interface
2. enable user land abstractions
3a. support successful ULAs with syntax
3b. support common native interface cases with core abstractions
roadmap
load styles/default.css
div.header { background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(72, 100, 180)), to(rgb(32, 60, 140))); background: -moz-linear-gradient(top, rgb(72, 100, 180), rgb(32, 60, 140)); padding: 0; height: 2.3em; font-size: 1.3em; line-height: 2.3em; font-weight: bold; text-align: center; text-shadow: #477 0px 1px 1px; color: white; font-weight: bold; margin: 0; z-index: 2;}
issue
out of sight,out of mind no checking
<div class="headerr"></div>
little abstraction
div.header { background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(72, 100, 180)), to(rgb(32, 60, 140))); background: -moz-linear-gradient(top, rgb(72, 100, 180), rgb(32, 60, 140)); padding: 0; height: 2.3em; font-size: 1.3em; line-height: 2.3em; font-weight: bold; text-align: center; text-shadow: #477 0px 1px 1px; color: white; font-weight: bold; margin: 0; z-index: 2;}
little abstraction
div.header { background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(72, 100, 180)), to(rgb(32, 60, 140))); background: -moz-linear-gradient(top, rgb(72, 100, 180), rgb(32, 60, 140)); padding: 0; height: 2.3em; font-size: 1.3em; line-height: 2.3em; font-weight: bold; text-align: center; text-shadow: #477 0px 1px 1px; color: white; font-weight: bold; margin: 0; z-index: 2;}
mixins
1. design core abstractions + native interface
2. enable user land abstractions
3a. support successful ULAs with syntax
3b. support common native interface cases with core abstractions