Zef Hemel, Eelco Visser
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
230,000/day
mobl: Een DSL voor mobiele applicatieontwikkeling
200,000/day
mobl: Een DSL voor mobiele applicatieontwikkeling
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
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
portability
deployment
mobl: Een DSL voor mobiele applicatieontwikkeling
WWW
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
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
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobile web apps
HTML
CSS
Javascript
SQL
cache
manifests
HTML
CSS
Javascript
SQL
cache
manifests
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
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);
}
synchronous programming
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);
}
});
...
asynchronous programming
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 inserted");
});
});
mix of loosely-coupled DSLs
poor tool-support for mixed-language projects
lack of abstraction in UI
asynchronous programming
mobl: Een DSL voor mobiele applicatieontwikkeling
demo
http://confplan.zef.me
mobl: Een DSL voor mobiele applicatieontwikkeling
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
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)) }
}
}
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)) }
}
}
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)) }
}
}
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)) }
}
}
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)) }
}
}
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)) }
}
}
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);
}
}
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); })
}
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); })
}
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); })
}
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); })
}
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); })
}
var pos = getPosition();
alert("Your location is: " + pos);
var pos = getPosition();
alert("Your location is: " + pos);
var pos;
getPosition(function(result) {
pos = result;
alert("Your location is: " + pos);
...
});
continuation-passing
style transformation
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 : Collection<Tag> (inverse: tasks)
}
entity Category {
	 name : String
	 tasks : Collection<Task> (inverse: category)
}
entity Tag {
	 name : String
	 tasks : Collection<Task> (inverse: tags)
}
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)
}
}
}
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)
}
}
}
control taskItem(t : Task) {
item(onclick={ taskDetails(t); }) {
checkBox(t.done)
" "
label(t.name)
contextMenu {
button("Remove", onclick={
remove(t);
})
}
}
}
control taskItem(t : Task) {
item(onclick={ taskDetails(t); }) {
checkBox(t.done)
" "
label(t.name)
contextMenu {
button("Remove", onclick={
remove(t);
})
}
}
}
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 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(); })
}
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(); })
}
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)
}
mobl: Een DSL voor mobiele applicatieontwikkeling
mobl: Een DSL voor mobiele applicatieontwikkeling
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>
what else is there?
service DataProvider {
resource getNearbyConferences(lat : Num, long : Num) : [JSON] {
uri = "/nearbyConferences"
}
resource fetchProgram(conferenceId : String) : [JSON] {
uri = "/conferenceProgram"
}
}
web services
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
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

More Related Content

PDF
mobl presentation @ IHomer
PDF
20180310 functional programming
PDF
Going Loopy - Adventures in Iteration with Google Go
PDF
mobl - model-driven engineering lecture
PDF
The Ring programming language version 1.5.4 book - Part 68 of 185
PDF
662305 LAB13
DOCX
Sumsem2014 15 cp0399-13-jun-2015_rm01_programs
PDF
The Ring programming language version 1.5.1 book - Part 62 of 180
mobl presentation @ IHomer
20180310 functional programming
Going Loopy - Adventures in Iteration with Google Go
mobl - model-driven engineering lecture
The Ring programming language version 1.5.4 book - Part 68 of 185
662305 LAB13
Sumsem2014 15 cp0399-13-jun-2015_rm01_programs
The Ring programming language version 1.5.1 book - Part 62 of 180

What's hot (20)

PDF
The Ring programming language version 1.6 book - Part 68 of 189
PDF
Rのスコープとフレームと環境と
PDF
Rデバッグあれこれ
DOC
Baitap tkw
PDF
GoLightly - a customisable virtual machine written in Go
PDF
The Ring programming language version 1.7 book - Part 72 of 196
PDF
Data structures lab
PDF
The Ring programming language version 1.10 book - Part 70 of 212
PDF
The Ring programming language version 1.3 book - Part 47 of 88
PDF
Groovy kind of test
PDF
TDC2016SP - Código funcional em Java: superando o hype
PDF
C++ TUTORIAL 7
PDF
The Ring programming language version 1.5.2 book - Part 41 of 181
PPTX
Scala meetup
PDF
Functional programming techniques in real-world microservices
PDF
Famo.us: From Zero to UI
PPTX
ZIO: Powerful and Principled Functional Programming in Scala
PDF
C++ TUTORIAL 6
PDF
The Ring programming language version 1.2 book - Part 30 of 84
PDF
The Ring programming language version 1.3 book - Part 36 of 88
The Ring programming language version 1.6 book - Part 68 of 189
Rのスコープとフレームと環境と
Rデバッグあれこれ
Baitap tkw
GoLightly - a customisable virtual machine written in Go
The Ring programming language version 1.7 book - Part 72 of 196
Data structures lab
The Ring programming language version 1.10 book - Part 70 of 212
The Ring programming language version 1.3 book - Part 47 of 88
Groovy kind of test
TDC2016SP - Código funcional em Java: superando o hype
C++ TUTORIAL 7
The Ring programming language version 1.5.2 book - Part 41 of 181
Scala meetup
Functional programming techniques in real-world microservices
Famo.us: From Zero to UI
ZIO: Powerful and Principled Functional Programming in Scala
C++ TUTORIAL 6
The Ring programming language version 1.2 book - Part 30 of 84
The Ring programming language version 1.3 book - Part 36 of 88
Ad

Viewers also liked (16)

PDF
Social Media Services Design &amp; Promote
PDF
Experimenting with Augmented Reality
PPTX
The Power Of A Press Release
PDF
Internet Marketing 101
PDF
Inbound Marketing 101
ODP
Software Transactioneel Geheugen
PPTX
Codereviews
PDF
Software Operation Knowledge
PDF
SEO 102 Seminar
PPTX
Van Idee Tot ISV
PDF
Devnology Back to School: Empirical Evidence on Modeling in Software Development
PDF
How To Be A Good Facebook Page Manager
PPTX
Unleash Your Domain With Greg Young
PDF
Introduction to Software Evolution: The Software Volcano
PDF
Learn a language : LISP
PDF
Small Business Internet Marketing Plan
Social Media Services Design &amp; Promote
Experimenting with Augmented Reality
The Power Of A Press Release
Internet Marketing 101
Inbound Marketing 101
Software Transactioneel Geheugen
Codereviews
Software Operation Knowledge
SEO 102 Seminar
Van Idee Tot ISV
Devnology Back to School: Empirical Evidence on Modeling in Software Development
How To Be A Good Facebook Page Manager
Unleash Your Domain With Greg Young
Introduction to Software Evolution: The Software Volcano
Learn a language : LISP
Small Business Internet Marketing Plan
Ad

Similar to mobl: Een DSL voor mobiele applicatieontwikkeling (20)

PDF
Software Language Design & Engineering
PDF
Software Language Design & Engineering: Mobl & Spoofax
PDF
PDF
mobl
PDF
Rethink Frontend Development With Elm
PDF
Linguistic Abstraction for the Web
PDF
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
PDF
There's more than web
PDF
Introduction to ECMAScript 2015
KEY
Pearson Mobile App Development
PDF
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
KEY
Kirin - Making Single Page Web Apps with a Native UI
PPTX
Advanced JavaScript
ZIP
Separation of Concerns in Web User Interfaces
PDF
Vaadin 7
PDF
Functional Web Development using Elm
PDF
Elm: give it a try
PPT
Building real-time collaborative apps with Ajax.org Platform
KEY
Gwt and Xtend
PPTX
Codestrong 2012 breakout session i os internals and best practices
Software Language Design & Engineering
Software Language Design & Engineering: Mobl & Spoofax
mobl
Rethink Frontend Development With Elm
Linguistic Abstraction for the Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
There's more than web
Introduction to ECMAScript 2015
Pearson Mobile App Development
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Kirin - Making Single Page Web Apps with a Native UI
Advanced JavaScript
Separation of Concerns in Web User Interfaces
Vaadin 7
Functional Web Development using Elm
Elm: give it a try
Building real-time collaborative apps with Ajax.org Platform
Gwt and Xtend
Codestrong 2012 breakout session i os internals and best practices

More from Devnology (20)

PDF
What do we really know about the differences between static and dynamic types?
PDF
Meetup at SIG: Meten is weten
PPTX
Slides Felienne Hermans Symposium EWI
PDF
Devnology auteursrecht en open source 20130205
PDF
The top 10 security issues in web applications
PDF
Hacking Smartcards & RFID
PDF
Learn a language : LISP
PDF
Devnology Back to School IV - Agility en Architectuur
PDF
Devnology Back to School III : Software impact
PDF
Devnology back toschool software reengineering
PPT
Devnology Workshop Genpro 2 feb 2011
PPT
Devnology Coding Dojo 05-01-2011
PDF
Spoofax: ontwikkeling van domeinspecifieke talen in Eclipse
PPTX
Unit testing and MVVM in Silverlight
PPTX
Devnology Fitnesse workshop
PDF
DNSSec: Internet achter de schermen
PPT
Code inspecties
PDF
Rascal Devnology Code Fest
PPT
Building an artificial game player in Smalltalk
PPTX
Reverse Engineering Spreadsheets
What do we really know about the differences between static and dynamic types?
Meetup at SIG: Meten is weten
Slides Felienne Hermans Symposium EWI
Devnology auteursrecht en open source 20130205
The top 10 security issues in web applications
Hacking Smartcards & RFID
Learn a language : LISP
Devnology Back to School IV - Agility en Architectuur
Devnology Back to School III : Software impact
Devnology back toschool software reengineering
Devnology Workshop Genpro 2 feb 2011
Devnology Coding Dojo 05-01-2011
Spoofax: ontwikkeling van domeinspecifieke talen in Eclipse
Unit testing and MVVM in Silverlight
Devnology Fitnesse workshop
DNSSec: Internet achter de schermen
Code inspecties
Rascal Devnology Code Fest
Building an artificial game player in Smalltalk
Reverse Engineering Spreadsheets

Recently uploaded (20)

PPTX
MicrosoftCybserSecurityReferenceArchitecture-April-2025.pptx
PPTX
Tartificialntelligence_presentation.pptx
PPT
What is a Computer? Input Devices /output devices
PDF
Hybrid horned lizard optimization algorithm-aquila optimizer for DC motor
PDF
A contest of sentiment analysis: k-nearest neighbor versus neural network
PDF
Developing a website for English-speaking practice to English as a foreign la...
PDF
August Patch Tuesday
PDF
From MVP to Full-Scale Product A Startup’s Software Journey.pdf
PDF
DASA ADMISSION 2024_FirstRound_FirstRank_LastRank.pdf
PDF
TrustArc Webinar - Click, Consent, Trust: Winning the Privacy Game
PPTX
Final SEM Unit 1 for mit wpu at pune .pptx
PPTX
The various Industrial Revolutions .pptx
PDF
Taming the Chaos: How to Turn Unstructured Data into Decisions
PDF
STKI Israel Market Study 2025 version august
PDF
Hindi spoken digit analysis for native and non-native speakers
PPTX
Web Crawler for Trend Tracking Gen Z Insights.pptx
PDF
sustainability-14-14877-v2.pddhzftheheeeee
PDF
DP Operators-handbook-extract for the Mautical Institute
PDF
Getting Started with Data Integration: FME Form 101
PDF
Assigned Numbers - 2025 - Bluetooth® Document
MicrosoftCybserSecurityReferenceArchitecture-April-2025.pptx
Tartificialntelligence_presentation.pptx
What is a Computer? Input Devices /output devices
Hybrid horned lizard optimization algorithm-aquila optimizer for DC motor
A contest of sentiment analysis: k-nearest neighbor versus neural network
Developing a website for English-speaking practice to English as a foreign la...
August Patch Tuesday
From MVP to Full-Scale Product A Startup’s Software Journey.pdf
DASA ADMISSION 2024_FirstRound_FirstRank_LastRank.pdf
TrustArc Webinar - Click, Consent, Trust: Winning the Privacy Game
Final SEM Unit 1 for mit wpu at pune .pptx
The various Industrial Revolutions .pptx
Taming the Chaos: How to Turn Unstructured Data into Decisions
STKI Israel Market Study 2025 version august
Hindi spoken digit analysis for native and non-native speakers
Web Crawler for Trend Tracking Gen Z Insights.pptx
sustainability-14-14877-v2.pddhzftheheeeee
DP Operators-handbook-extract for the Mautical Institute
Getting Started with Data Integration: FME Form 101
Assigned Numbers - 2025 - Bluetooth® Document

mobl: Een DSL voor mobiele applicatieontwikkeling