57. Scala 101
Traits
trait A { def a = "aaa" }
trait B { def b = "bbb" }
14
58. Scala 101
Traits
trait A { def a = "aaa" }
trait B { def b = "bbb" }
class C extends A with B {
def c = "ccc"
}
14
59. Scala 101
Traits
trait A { def a = "aaa" }
trait B { def b = "bbb" }
class C extends A with B {
def c = "ccc"
}
val c = new C
println(c.a + c.b + c.c)
14
60. Scala 101
Traits
trait A { def a = "aaa" }
trait B { def b = "bbb" }
class C extends A with B {
def c = "ccc"
}
val c = new C
println(c.a + c.b + c.c)
14
61. Scala 101
Traits
trait A { def a = "aaa" }
trait B { def b = "bbb" }
class C extends A with B {
def c = "ccc"
}
val c = new C
println(c.a + c.b + c.c) aaabbbccc
14
85. R.java
public final class R {
...
public static final class id {
public static final int login=0x7f050001;
}
...
public static final class string {
public static final int login_button_text=0x7f040003;
}
}
23
86. R.java
public final class R {
...
public static final class id {
public static final int login=0x7f050001;
}
...
public static final class string {
public static final int login_button_text=0x7f040003;
}
}
23
87. R.java
public final class R {
...
public static final class id {
public static final int login=0x7f050001;
}
...
public static final class string {
public static final int login_button_text=0x7f040003;
}
}
23
88. R.java
Button?
public final class R {
...
public static final class id {
public static final int login=0x7f050001;
}
...
public static final class string {
public static final int login_button_text=0x7f040003;
}
}
23
89. R.java
public final class R {
...
public static final class id {
public static final int login=0x7f050001;
}
...
public static final class string {
public static final int login_button_text=0x7f040003;
}
}
23
106. Scala 101
Anonymous functions
class Printer[A](list: List[A]) {
def printSome(p: A => Boolean): Unit =
for (elem <- list)
if (p(elem))
println(elem.toString)
}
29
107. Scala 101
Anonymous functions
class Printer[A](list: List[A]) {
def printSome(p: A => Boolean): Unit =
for (elem <- list)
if (p(elem))
println(elem.toString)
}
29
108. Scala 101
Anonymous functions
class Printer[A](list: List[A]) {
def printSome(p: A => Boolean): Unit =
for (elem <- list)
if (p(elem))
println(elem.toString)
}
29
109. Scala 101
Anonymous functions
class Printer[A](list: List[A]) {
def printSome(p: A => Boolean): Unit =
for (elem <- list)
if (p(elem))
println(elem.toString)
}
29
110. Scala 101
Anonymous functions
class Printer[A](list: List[A]) {
def printSome(p: A => Boolean): Unit =
for (elem <- list)
if (p(elem))
println(elem.toString)
}
29
111. Scala 101
Anonymous functions
class Printer[A](list: List[A]) {
def printSome(p: A => Boolean): Unit =
for (elem <- list)
if (p(elem))
println(elem.toString)
}
val printer = new Printer(List("yo", "doh", "hi"))
printer.printSome { e => e.contains("o") }
29
112. Scala 101
Anonymous functions
class Printer[A](list: List[A]) {
def printSome(p: A => Boolean): Unit =
for (elem <- list)
if (p(elem))
println(elem.toString)
}
val printer = new Printer(List("yo", "doh", "hi"))
printer.printSome { e => e.contains("o") }
29
113. Scala 101
Anonymous functions
class Printer[A](list: List[A]) {
def printSome(p: A => Boolean): Unit =
for (elem <- list)
if (p(elem))
println(elem.toString)
}
val printer = new Printer(List("yo", "doh", "hi"))
printer.printSome { e => e.contains("o") }
29
114. Scala 101
Anonymous functions
class Printer[A](list: List[A]) {
def printSome(p: A => Boolean): Unit =
for (elem <- list)
if (p(elem))
println(elem.toString)
}
val printer = new Printer(List("yo", "doh", "hi"))
printer.printSome { e => e.contains("o") }
29
115. Scala 101
Anonymous functions
class Printer[A](list: List[A]) {
def printSome(p: A => Boolean): Unit =
for (elem <- list)
if (p(elem))
println(elem.toString)
}
val printer = new Printer(List("yo", "doh", "hi"))
printer.printSome { e => e.contains("o") }
29
116. Scala 101
Anonymous functions
class Printer[A](list: List[A]) {
def printSome(p: A => Boolean): Unit =
for (elem <- list)
if (p(elem))
println(elem.toString)
}
val printer = new Printer(List("yo", "doh", "hi"))
printer.printSome { e => e.contains("o") }
printer.printSome(_.contains("o"))
29
117. Scala 101
Anonymous functions
class Printer[A](list: List[A]) {
def printSome(p: A => Boolean): Unit =
for (elem <- list)
if (p(elem))
println(elem.toString)
}
val printer = new Printer(List("yo", "doh", "hi"))
printer.printSome { e => e.contains("o") }
printer.printSome(_.contains("o"))
29
218. Actors
case class Routing(success: Option[Actor],
failure: Option[Actor])
case class HttpRequestMsg(href: URL, routing: Routing)
retrieveData.onClick {
Connection ! new HttpRequestMsg(
"http://s.no/dig/url",
new Routing(Some(ModelFactory), Some(GUI)))
}
46
219. Actors
case class Routing(success: Option[Actor],
failure: Option[Actor])
case class HttpRequestMsg(href: URL, routing: Routing)
retrieveData.onClick {
Connection ! new HttpRequestMsg(
"http://s.no/dig/url",
new Routing(Some(ModelFactory), Some(GUI)))
}
46
220. Actors
case class Routing(success: Option[Actor],
failure: Option[Actor])
case class HttpRequestMsg(href: URL, routing: Routing)
retrieveData.onClick {
Connection ! new HttpRequestMsg(
"http://s.no/dig/url",
new Routing(Some(ModelFactory), Some(GUI)))
}
46
221. Actors
case class Routing(success: Option[Actor],
failure: Option[Actor])
case class HttpRequestMsg(href: URL, routing: Routing)
retrieveData.onClick {
Connection ! new HttpRequestMsg(
"http://s.no/dig/url",
new Routing(Some(ModelFactory), Some(GUI)))
}
46
222. Actors
case class Routing(success: Option[Actor],
failure: Option[Actor])
case class HttpRequestMsg(href: URL, routing: Routing)
retrieveData.onClick {
Connection ! new HttpRequestMsg(
"http://s.no/dig/url",
new Routing(Some(ModelFactory), Some(GUI)))
}
46
223. Actors
case class Routing(success: Option[Actor],
failure: Option[Actor])
case class HttpRequestMsg(href: URL, routing: Routing)
retrieveData.onClick {
Connection ! new HttpRequestMsg(
"http://s.no/dig/url",
new Routing(Some(ModelFactory), Some(GUI)))
}
46
224. Actors
case class Routing(success: Option[Actor],
failure: Option[Actor])
case class HttpRequestMsg(href: URL, routing: Routing)
retrieveData.onClick {
Connection ! new HttpRequestMsg(
"http://s.no/dig/url",
new Routing(Some(ModelFactory), Some(GUI)))
}
46
225. Actors
case class Routing(success: Option[Actor],
failure: Option[Actor])
case class HttpRequestMsg(href: URL, routing: Routing)
retrieveData.onClick {
Connection ! new HttpRequestMsg(
"http://s.no/dig/url",
new Routing(Some(ModelFactory), Some(GUI)))
}
46
226. Actors
case class Routing(success: Option[Actor],
failure: Option[Actor])
case class HttpRequestMsg(href: URL, routing: Routing)
retrieveData.onClick {
Connection ! new HttpRequestMsg(
"http://s.no/dig/url",
new Routing(Some(ModelFactory), Some(GUI)))
}
46
227. Actors
case class Routing(success: Option[Actor],
failure: Option[Actor])
case class HttpRequestMsg(href: URL, routing: Routing)
retrieveData.onClick {
Connection ! new HttpRequestMsg(
"http://s.no/dig/url",
new Routing(Some(ModelFactory), Some(GUI)))
}
46
228. Actors
case class Routing(success: Option[Actor],
failure: Option[Actor])
case class HttpRequestMsg(href: URL, routing: Routing)
retrieveData.onClick {
Connection ! new HttpRequestMsg(
"http://s.no/dig/url",
new Routing(Some(ModelFactory), Some(GUI)))
}
46
229. Actors
case class Routing(success: Option[Actor],
failure: Option[Actor])
case class HttpRequestMsg(href: URL, routing: Routing)
retrieveData.onClick {
Connection ! new HttpRequestMsg(
"http://s.no/dig/url",
new Routing(Some(ModelFactory), Some(GUI)))
}
46
230. Actors
case class Routing(success: Option[Actor],
failure: Option[Actor])
case class HttpRequestMsg(href: URL, routing: Routing)
retrieveData.onClick {
Connection ! new HttpRequestMsg(
"http://s.no/dig/url",
new Routing(Some(ModelFactory), Some(GUI)))
}
46
231. Actor
object Connection extends Actor {
def retrieve(href: String): Either[Node, Failure] =
Right(new Failure())
def act {
loop {
react {
case HttpRequestMsg(href, Routing(success, failure)) =>
retrieve(href) match {
case Left(node) => success.map(_ ! node)
case Right(error) => failure.map(_ ! error)
}
case _ => println("Say what")
}
}
}
start
}
47
232. Actor
object Connection extends Actor {
def retrieve(href: String): Either[Node, Failure] =
Right(new Failure())
def act {
loop {
react {
case HttpRequestMsg(href, Routing(success, failure)) =>
retrieve(href) match {
case Left(node) => success.map(_ ! node)
case Right(error) => failure.map(_ ! error)
}
case _ => println("Say what")
}
}
}
start
}
47
233. Actor
object Connection extends Actor {
def retrieve(href: String): Either[Node, Failure] =
Right(new Failure())
def act {
loop {
react {
case HttpRequestMsg(href, Routing(success, failure)) =>
retrieve(href) match {
case Left(node) => success.map(_ ! node)
case Right(error) => failure.map(_ ! error)
}
case _ => println("Say what")
}
}
}
start
}
47
234. Actor
object Connection extends Actor {
def retrieve(href: String): Either[Node, Failure] =
Right(new Failure())
def act {
loop {
react {
case HttpRequestMsg(href, Routing(success, failure)) =>
retrieve(href) match {
case Left(node) => success.map(_ ! node)
case Right(error) => failure.map(_ ! error)
}
case _ => println("Say what")
}
}
}
start
}
47
235. Actor
object Connection extends Actor {
def retrieve(href: String): Either[Node, Failure] =
Right(new Failure())
def act {
loop {
react {
case HttpRequestMsg(href, Routing(success, failure)) =>
retrieve(href) match {
case Left(node) => success.map(_ ! node)
case Right(error) => failure.map(_ ! error)
}
case _ => println("Say what")
}
}
}
start
}
47
236. Actor
object Connection extends Actor {
def retrieve(href: String): Either[Node, Failure] =
Right(new Failure())
def act {
loop {
react {
case HttpRequestMsg(href, Routing(success, failure)) =>
retrieve(href) match {
case Left(node) => success.map(_ ! node)
case Right(error) => failure.map(_ ! error)
}
case _ => println("Say what")
}
}
}
start
}
47
237. Actor
object Connection extends Actor {
def retrieve(href: String): Either[Node, Failure] =
Right(new Failure())
def act {
loop {
react {
case HttpRequestMsg(href, Routing(success, failure)) =>
retrieve(href) match {
case Left(node) => success.map(_ ! node)
case Right(error) => failure.map(_ ! error)
}
case _ => println("Say what")
}
}
}
start
}
47
238. Actor
object Connection extends Actor {
def retrieve(href: String): Either[Node, Failure] =
Right(new Failure())
def act {
loop {
react {
case HttpRequestMsg(href, Routing(success, failure)) =>
retrieve(href) match {
case Left(node) => success.map(_ ! node)
case Right(error) => failure.map(_ ! error)
}
case _ => println("Say what")
}
}
}
start
}
47
239. Actor
object Connection extends Actor {
def retrieve(href: String): Either[Node, Failure] =
Right(new Failure())
def act {
loop {
react {
case HttpRequestMsg(href, Routing(success, failure)) =>
retrieve(href) match {
case Left(node) => success.map(_ ! node)
case Right(error) => failure.map(_ ! error)
}
case _ => println("Say what")
}
}
}
start
}
47
240. Actor
object Connection extends Actor {
def retrieve(href: String): Either[Node, Failure] =
Right(new Failure())
def act {
loop {
react {
case HttpRequestMsg(href, Routing(success, failure)) =>
retrieve(href) match {
case Left(node) => success.map(_ ! node)
case Right(error) => failure.map(_ ! error)
}
case _ => println("Say what")
}
}
}
start
}
47
241. Actor
object Connection extends Actor {
def retrieve(href: String): Either[Node, Failure] =
Right(new Failure())
def act {
loop {
react {
case HttpRequestMsg(href, Routing(success, failure)) =>
retrieve(href) match {
case Left(node) => success.map(_ ! node)
case Right(error) => failure.map(_ ! error)
}
case _ => println("Say what")
}
}
}
start
}
47
242. Actor
object Connection extends Actor {
def retrieve(href: String): Either[Node, Failure] =
Right(new Failure())
def act {
loop {
react {
case HttpRequestMsg(href, Routing(success, failure)) =>
retrieve(href) match {
case Left(node) => success.map(_ ! node)
case Right(error) => failure.map(_ ! error)
}
case _ => println("Say what")
}
}
}
start
}
47
243. Actor
object Connection extends Actor {
def retrieve(href: String): Either[Node, Failure] =
Right(new Failure())
def act {
loop {
react {
case HttpRequestMsg(href, Routing(success, failure)) =>
retrieve(href) match {
case Left(node) => success.map(_ ! node)
case Right(error) => failure.map(_ ! error)
}
case _ => println("Say what")
}
}
}
start
}
47
Fringe: J2ME and Windows Mobile
No working market
Mainstream: Android and iPhone
Android bigger than iPhone
GOOGLE
Customisable: Open source, Linux
Exploding platform
Mobile, TV, Pad
Specialised devices will come
Telephones running UNIX
(OpenCore media library)
Dalvik ~= JVM
Develop in java
Harmony - Subset base class library
GUI, bluetooth, WiFi, telephony, location, other hardware
Telephones running UNIX
(OpenCore media library)
Dalvik ~= JVM
Develop in java
Harmony - Subset base class library
GUI, bluetooth, WiFi, telephony, location, other hardware
Telephones running UNIX
(OpenCore media library)
Dalvik ~= JVM
Develop in java
Harmony - Subset base class library
GUI, bluetooth, WiFi, telephony, location, other hardware
Telephones running UNIX
(OpenCore media library)
Dalvik ~= JVM
Develop in java
Harmony - Subset base class library
GUI, bluetooth, WiFi, telephony, location, other hardware
Telephones running UNIX
(OpenCore media library)
Dalvik ~= JVM
Develop in java
Harmony - Subset base class library
GUI, bluetooth, WiFi, telephony, location, other hardware
Telephones running UNIX
(OpenCore media library)
Dalvik ~= JVM
Develop in java
Harmony - Subset base class library
GUI, bluetooth, WiFi, telephony, location, other hardware
Telephones running UNIX
(OpenCore media library)
Dalvik ~= JVM
Develop in java
Harmony - Subset base class library
GUI, bluetooth, WiFi, telephony, location, other hardware
Telephones running UNIX
(OpenCore media library)
Dalvik ~= JVM
Develop in java
Harmony - Subset base class library
GUI, bluetooth, WiFi, telephony, location, other hardware
Telephones running UNIX
(OpenCore media library)
Dalvik ~= JVM
Develop in java
Harmony - Subset base class library
GUI, bluetooth, WiFi, telephony, location, other hardware
Telephones running UNIX
(OpenCore media library)
Dalvik ~= JVM
Develop in java
Harmony - Subset base class library
GUI, bluetooth, WiFi, telephony, location, other hardware
Telephones running UNIX
(OpenCore media library)
Dalvik ~= JVM
Develop in java
Harmony - Subset base class library
GUI, bluetooth, WiFi, telephony, location, other hardware
Telephones running UNIX
(OpenCore media library)
Dalvik ~= JVM
Develop in java
Harmony - Subset base class library
GUI, bluetooth, WiFi, telephony, location, other hardware
Build system
Used in Scala-community
build.properties
Version, project name, scala version
build - project definition
plugins - definition of plugins used
build.properties
Version, project name, scala version
build - project definition
plugins - definition of plugins used
build.properties
Version, project name, scala version
build - project definition
plugins - definition of plugins used
ProjectInfo - external properties, paths
Eclipsify
Eclipse for nice colours
ProjectInfo - external properties, paths
Eclipsify
Eclipse for nice colours
ProjectInfo - external properties, paths
Eclipsify
Eclipse for nice colours
ProGuard
Reflection
Hello world example -> 5kb
Littlebro + 2.7.7 -> 100kb
Littlebro + 2.8.0 -> 200kb
ProGuard
Reflection
Hello world example -> 5kb
Littlebro + 2.7.7 -> 100kb
Littlebro + 2.8.0 -> 200kb
ProGuard
Reflection
Hello world example -> 5kb
Littlebro + 2.7.7 -> 100kb
Littlebro + 2.8.0 -> 200kb
ProGuard
Reflection
Hello world example -> 5kb
Littlebro + 2.7.7 -> 100kb
Littlebro + 2.8.0 -> 200kb
ProGuard
Reflection
Hello world example -> 5kb
Littlebro + 2.7.7 -> 100kb
Littlebro + 2.8.0 -> 200kb
ProGuard
Reflection
Hello world example -> 5kb
Littlebro + 2.7.7 -> 100kb
Littlebro + 2.8.0 -> 200kb
ProGuard
Reflection
Hello world example -> 5kb
Littlebro + 2.7.7 -> 100kb
Littlebro + 2.8.0 -> 200kb
ProGuard
Reflection
Hello world example -> 5kb
Littlebro + 2.7.7 -> 100kb
Littlebro + 2.8.0 -> 200kb
ProGuard
Reflection
Hello world example -> 5kb
Littlebro + 2.7.7 -> 100kb
Littlebro + 2.8.0 -> 200kb
ProGuard
Reflection
Hello world example -> 5kb
Littlebro + 2.7.7 -> 100kb
Littlebro + 2.8.0 -> 200kb
ProGuard
Reflection
Hello world example -> 5kb
Littlebro + 2.7.7 -> 100kb
Littlebro + 2.8.0 -> 200kb
R[esources].java
Aids resource lookup
Type lost
Type lost
Type lost
Type lost
Needs cast
Scala accepts casting very reluctantly
asInstanceOf is a method (final)
Accept a generic argument
Needs cast
Scala accepts casting very reluctantly
asInstanceOf is a method (final)
Accept a generic argument
Needs cast
Scala accepts casting very reluctantly
asInstanceOf is a method (final)
Accept a generic argument
Needs cast
Scala accepts casting very reluctantly
asInstanceOf is a method (final)
Accept a generic argument
Needs cast
Scala accepts casting very reluctantly
asInstanceOf is a method (final)
Accept a generic argument
Generated by SBT android plugin
with TypedActivity
Generated by SBT android plugin
with TypedActivity
Generated by SBT android plugin
with TypedActivity
Generated by SBT android plugin
with TypedActivity
Generated by SBT android plugin
with TypedActivity
In java
In scala
Can we do better?
Button extends View
Can not add functions
Button extends View
Can not add functions
Button extends View
Can not add functions
Add methods to class
Implicit conversion
Must be imported
onClick
View => Unit
Add methods to class
Implicit conversion
Must be imported
onClick
View => Unit
Add methods to class
Implicit conversion
Must be imported
onClick
View => Unit
Add methods to class
Implicit conversion
Must be imported
onClick
View => Unit
Add methods to class
Implicit conversion
Must be imported
onClick
View => Unit
Add methods to class
Implicit conversion
Must be imported
onClick
View => Unit
Add methods to class
Implicit conversion
Must be imported
onClick
View => Unit
Add methods to class
Implicit conversion
Must be imported
onClick
View => Unit
Add methods to class
Implicit conversion
Must be imported
onClick
View => Unit
Add methods to class
Implicit conversion
Must be imported
onClick
View => Unit
I.e calculation or network
5 seconds & a touch
Developer guide
Design for responsiveness
Android provided asynchronous task
Drawback: Single thread; not thread pool
Android provided asynchronous task
Drawback: Single thread; not thread pool
Android provided asynchronous task
Drawback: Single thread; not thread pool
Android provided asynchronous task
Drawback: Single thread; not thread pool
Android provided asynchronous task
Drawback: Single thread; not thread pool
We need to update GUI
Activity.runOnUiThread(Runnable)
Activity.runOnUiThread(Runnable)
Activity.runOnUiThread(Runnable)
Activity.runOnUiThread(Runnable)
Combined version
Drop noise code
Same trick as with listeners
Combined version
Drop noise code
Same trick as with listeners
Combined version
Drop noise code
Same trick as with listeners
Combined version
Drop noise code
Same trick as with listeners
Combined version
Drop noise code
Same trick as with listeners
Combined version
Drop noise code
Same trick as with listeners
Combined version
Drop noise code
Same trick as with listeners
Combined version
Drop noise code
Same trick as with listeners
Drop more noise code
Drop AsyncTask object
Drop execute