Scala on androids

  • 2,131 views
Uploaded on

Talk on Scala development on Android

Talk on Scala development on Android

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
  • Presentation at JavaZone: http://streaming.java.no/tcs/?id=97A469FD-3DDE-4692-85E9-651CFFCCC918 (in norwegian)
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
2,131
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
89
Comments
1
Likes
7

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide



  • 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






















  • Pass data needed with success and failure path
  • Pass data needed with success and failure path
  • Pass data needed with success and failure path
  • Pass data needed with success and failure path
  • Pass data needed with success and failure path
  • Pass data needed with success and failure path
  • Pass data needed with success and failure path
  • Pass data needed with success and failure path
  • Pass data needed with success and failure path
  • Pass data needed with success and failure path
  • Pass data needed with success and failure path
  • Pass data needed with success and failure path
  • Pass data needed with success and failure path
  • Pass data needed with success and failure path




































Transcript

  • 1. Scala on Androids Thor Åge Eldby @thoraageeldby 1
  • 2. Me C/C ++ a av lJ na so J2M r Pe E Java An dro id Scala 2
  • 3. Arktekk • Started 2007 • Consultancy and training 3
  • 4. Android Fringe to mainstream 4
  • 5. Android 101 5
  • 6. Android 101 Linux 5
  • 7. Android 101 OpenCore Linux 5
  • 8. Android 101 OpenCore SQLite Linux 5
  • 9. Android 101 OpenGL OpenCore SQLite ES Linux 5
  • 10. Android 101 OpenGL OpenCore SQLite WebKit ES Linux 5
  • 11. Android 101 OpenGL OpenCore SQLite WebKit Other ES Linux 5
  • 12. Android 101 Dalvik OpenGL OpenCore SQLite WebKit Other ES Linux 5
  • 13. Android 101 Apache Harmony Dalvik OpenGL OpenCore SQLite WebKit Other ES Linux 5
  • 14. Android 101 Apache HttpClient Harmony Dalvik OpenGL OpenCore SQLite WebKit Other ES Linux 5
  • 15. Android 101 Apache HttpClient org.json Harmony Dalvik OpenGL OpenCore SQLite WebKit Other ES Linux 5
  • 16. Android 101 Apache HttpClient org.json DOM/SAX Harmony Dalvik OpenGL OpenCore SQLite WebKit Other ES Linux 5
  • 17. Android 101 Apache HttpClient org.json DOM/SAX Android Harmony Dalvik OpenGL OpenCore SQLite WebKit Other ES Linux 5
  • 18. Android SDK
  • 19. Android SDK .java files
  • 20. Android SDK .java files
  • 21. Android SDK .java files javac
  • 22. Android SDK .java files javac
  • 23. Android SDK .java files javac .class files
  • 24. Android SDK .java files javac .class files
  • 25. Android SDK .java files javac .class files dx
  • 26. Android SDK .java files javac .class files dx
  • 27. Android SDK .java files javac .class files .dex dx file
  • 28. Android SDK .java files javac .class files .dex dx file
  • 29. Android SDK .java files javac .class files .dex resou- dx file rces
  • 30. Android SDK .java files javac .class files .dex resou- dx file rces
  • 31. Android SDK .java files javac aapt .class files .dex resou- dx file rces
  • 32. Android SDK .java files javac aapt .class files .dex resou- dx file rces
  • 33. Android SDK .java files .apk file javac aapt .class files .dex resou- dx file rces
  • 34. Android SDK .java files .apk file javac aapt .class files .dex resou- dx file rces
  • 35. Android SDK .java adb files .apk file javac aapt .class files .dex resou- dx file rces
  • 36. Android SDK .java adb files .apk file javac aapt .class files .dex resou- dx file rces
  • 37. Android SDK .java adb files .apk file javac aapt .class files .dex resou- dx file rces
  • 38. Android SDK .java adb files .apk file javac aapt .class files .dex resou- dx file rces 6
  • 39. Android Development Components 7
  • 40. Android Development Components Activity Text Text Done Cancel 7
  • 41. Android Development Components Activity Service Text Text Done Cancel 7
  • 42. Android Development Components Activity Service Broadcast- Receiver Text Text Done Cancel 7
  • 43. Android Development Components Activity Service Broadcast- Receiver Text Text Done Cancel Intent 7
  • 44. Android Development Components Activity Service Broadcast- Receiver Text Text Done Cancel Intent 7
  • 45. Android Development Components Activity Service Broadcast- Receiver Text Text Done Cancel Intent 7
  • 46. Littlebro http://github.com/thoraage/littlebro-android http://github.com/thoraage/jmx-rest-access 8
  • 47. Overview Android Littlebro 9
  • 48. Overview Android Littlebro Jetty / LIFT JMX REST Access 9
  • 49. Overview Android Littlebro Jetty / LIFT JMX REST Access Glassfish JMX 9
  • 50. Demo 10
  • 51. SBT • http://code.google.com/p/simple-build-tool/ 11
  • 52. SBT • Command line • Maven source structure • Configured in Scala 12
  • 53. SBT Structure |-- project | |-- build | | `-- Littlebro.scala | |-- build.properties | `-- plugins | `-- Plugins.scala 13
  • 54. SBT Structure |-- project | |-- build | | `-- Littlebro.scala | |-- build.properties | `-- plugins | `-- Plugins.scala 13
  • 55. SBT Structure |-- project | |-- build | | `-- Littlebro.scala | |-- build.properties | `-- plugins | `-- Plugins.scala 13
  • 56. SBT Structure |-- project | |-- build | | `-- Littlebro.scala | |-- build.properties | `-- plugins | `-- Plugins.scala 13
  • 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
  • 62. Project class Littlebro(info: ProjectInfo) extends AndroidProject(info) with TypedResources with Eclipsify { override def androidPlatformName = "android-1.5" } 15
  • 63. Project class Littlebro(info: ProjectInfo) extends AndroidProject(info) with TypedResources with Eclipsify { override def androidPlatformName = "android-1.5" } 15
  • 64. Project class Littlebro(info: ProjectInfo) extends AndroidProject(info) with TypedResources with Eclipsify { override def androidPlatformName = "android-1.5" } 15
  • 65. Project class Littlebro(info: ProjectInfo) extends AndroidProject(info) with TypedResources with Eclipsify { override def androidPlatformName = "android-1.5" } 15
  • 66. SBT & Android • http://github.com/jberkel/android-plugin 16
  • 67. SBT & Android • http://github.com/jberkel/android-plugin scalac 16
  • 68. SBT & Android • http://github.com/jberkel/android-plugin scalac 16
  • 69. SBT & Android • http://github.com/jberkel/android-plugin scalac .class files 16
  • 70. SBT & Android • http://github.com/jberkel/android-plugin scalac .class files 16
  • 71. SBT & Android • http://github.com/jberkel/android-plugin scalac .class files ProGuard 16
  • 72. SBT & Android • http://github.com/jberkel/android-plugin scalac .class files ProGuard 16
  • 73. SBT & Android • http://github.com/jberkel/android-plugin scalac .class files less .class ProGuard files 16
  • 74. SBT & Android • http://github.com/jberkel/android-plugin scalac .class files less .class ProGuard files 16
  • 75. SBT & Android • http://github.com/jberkel/android-plugin scalac .class files less .class ProGuard files dx 16
  • 76. SBT & Android • http://github.com/jberkel/android-plugin scalac .class files less .class ProGuard files dx 16
  • 77. SBT & Android • http://github.com/jberkel/android-plugin scalac ... .class files less .class ProGuard files dx 16
  • 78. Demo 17
  • 79. SBT & Idea • http://github.com/mpeltonen/sbt-idea-plugin • Hacked to work with sbt-android-plugin: http://github.com/thoraage/sbt-idea-plugin • Generates project files • SBT processor 18
  • 80. SBT & Eclipse • http://github.com/musk/SbtEclipsify • Not tested with Android 19
  • 81. Scala on Androids Quick wins 20
  • 82. Resources Resource xml’s and R.java 21
  • 83. Layout definition <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:a="http://schemas.android.com/apk/res/android" ...> <TextView a:text="@string/host_address_text" .../> <EditText a:id="@+id/hostAddress" .../> <Button a:id="@+id/login" a:text="@string/login_button_text" .../> </LinearLayout> 22
  • 84. Layout definition <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:a="http://schemas.android.com/apk/res/android" ...> <TextView a:text="@string/host_address_text" .../> <EditText a:id="@+id/hostAddress" .../> <Button a:id="@+id/login" a:text="@string/login_button_text" .../> </LinearLayout> 22
  • 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
  • 90. R.java usage • In java • Button login = (Button) findViewById(R.id.login); 24
  • 91. R.java usage • In java • Button login = (Button) findViewById(R.id.login); 24
  • 92. R.java usage • In java • Button login = (Button) findViewById(R.id.login); 24
  • 93. R.java usage • In java • Button login = (Button) findViewById(R.id.login); • In Scala • val login = findViewById(R.id.login).asInstanceOf[Button] 24
  • 94. R.java usage • In java • Button login = (Button) findViewById(R.id.login); • In Scala • val login = findViewById(R.id.login).asInstanceOf[Button] 24
  • 95. R.java usage • In java • Button login = (Button) findViewById(R.id.login); • In Scala • val login = findViewById(R.id.login).asInstanceOf[Button] 24
  • 96. TR.scala ... object TR { val login = TypedResource[android.widget.Button](R.id.login) } ... trait TypedActivityHolder { def activity: Activity def findView[T](tr: TypedResource[T]) = activity.findViewById(tr.id).asInstanceOf[T] } trait TypedActivity extends Activity with TypedActivityHolder { def activity = this } 25
  • 97. TR.scala ... object TR { val login = TypedResource[android.widget.Button](R.id.login) } ... trait TypedActivityHolder { def activity: Activity def findView[T](tr: TypedResource[T]) = activity.findViewById(tr.id).asInstanceOf[T] } trait TypedActivity extends Activity with TypedActivityHolder { def activity = this } 25
  • 98. TR.scala ... object TR { val login = TypedResource[android.widget.Button](R.id.login) } ... trait TypedActivityHolder { def activity: Activity def findView[T](tr: TypedResource[T]) = activity.findViewById(tr.id).asInstanceOf[T] } trait TypedActivity extends Activity with TypedActivityHolder { def activity = this } 25
  • 99. TR.scala ... object TR { val login = TypedResource[android.widget.Button](R.id.login) } ... trait TypedActivityHolder { def activity: Activity def findView[T](tr: TypedResource[T]) = activity.findViewById(tr.id).asInstanceOf[T] } trait TypedActivity extends Activity with TypedActivityHolder { def activity = this } 25
  • 100. TR.scala ... object TR { val login = TypedResource[android.widget.Button](R.id.login) } ... trait TypedActivityHolder { def activity: Activity def findView[T](tr: TypedResource[T]) = activity.findViewById(tr.id).asInstanceOf[T] } trait TypedActivity extends Activity with TypedActivityHolder { def activity = this } 25
  • 101. TR.scala ... object TR { val login = TypedResource[android.widget.Button](R.id.login) } ... trait TypedActivityHolder { def activity: Activity def findView[T](tr: TypedResource[T]) = activity.findViewById(tr.id).asInstanceOf[T] } trait TypedActivity extends Activity with TypedActivityHolder { def activity = this } 25
  • 102. TR.java usage • With TR.scala • val login = findView(TR.login) 26
  • 103. Listeners 27
  • 104. Listeners login.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { ... } } 28
  • 105. Listeners login.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { ... } } login.setOnClickListener(new View.OnClickListener() { override def onClick(view: View) { ... } }) 28
  • 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
  • 118. Listeners def onClick(f: View => Unit) { setOnClickListener(new View.OnClickListener { override def onClick(v: View) = f(v) }) } 30
  • 119. Listeners def onClick(f: View => Unit) { setOnClickListener(new View.OnClickListener { override def onClick(v: View) = f(v) }) } 30
  • 120. Listeners def onClick(f: View => Unit) { setOnClickListener(new View.OnClickListener { override def onClick(v: View) = f(v) }) } 30
  • 121. Listeners def onClick(f: View => Unit) { setOnClickListener(new View.OnClickListener { override def onClick(v: View) = f(v) }) } login.onClick { view => ... } 30
  • 122. Scala 101 Implicit conversion class AmendedString(s: String) { def rot13 = new String(for (c <- s) yield rotC(c)) def rotC(c: Char) = (((c - 97) + 13) % 26 + 97).asInstanceOf[Char] } 31
  • 123. Scala 101 Implicit conversion class AmendedString(s: String) { def rot13 = new String(for (c <- s) yield rotC(c)) def rotC(c: Char) = (((c - 97) + 13) % 26 + 97).asInstanceOf[Char] } 31
  • 124. Scala 101 Implicit conversion class AmendedString(s: String) { def rot13 = new String(for (c <- s) yield rotC(c)) def rotC(c: Char) = (((c - 97) + 13) % 26 + 97).asInstanceOf[Char] } 31
  • 125. Scala 101 Implicit conversion class AmendedString(s: String) { def rot13 = new String(for (c <- s) yield rotC(c)) def rotC(c: Char) = (((c - 97) + 13) % 26 + 97).asInstanceOf[Char] } new AmendedString("yodude").rot13 31
  • 126. Scala 101 Implicit conversion class AmendedString(s: String) { def rot13 = new String(for (c <- s) yield rotC(c)) def rotC(c: Char) = (((c - 97) + 13) % 26 + 97).asInstanceOf[Char] } new AmendedString("yodude").rot13 implicit def string2amendedString(s: String) = new AmendedString(s) 31
  • 127. Scala 101 Implicit conversion class AmendedString(s: String) { def rot13 = new String(for (c <- s) yield rotC(c)) def rotC(c: Char) = (((c - 97) + 13) % 26 + 97).asInstanceOf[Char] } new AmendedString("yodude").rot13 implicit def string2amendedString(s: String) = new AmendedString(s) 31
  • 128. Scala 101 Implicit conversion class AmendedString(s: String) { def rot13 = new String(for (c <- s) yield rotC(c)) def rotC(c: Char) = (((c - 97) + 13) % 26 + 97).asInstanceOf[Char] } new AmendedString("yodude").rot13 implicit def string2amendedString(s: String) = new AmendedString(s) 31
  • 129. Scala 101 Implicit conversion class AmendedString(s: String) { def rot13 = new String(for (c <- s) yield rotC(c)) def rotC(c: Char) = (((c - 97) + 13) % 26 + 97).asInstanceOf[Char] } new AmendedString("yodude").rot13 implicit def string2amendedString(s: String) = new AmendedString(s) 31
  • 130. Scala 101 Implicit conversion class AmendedString(s: String) { def rot13 = new String(for (c <- s) yield rotC(c)) def rotC(c: Char) = (((c - 97) + 13) % 26 + 97).asInstanceOf[Char] } new AmendedString("yodude").rot13 implicit def string2amendedString(s: String) = new AmendedString(s) "yodude".rot13 31
  • 131. Scala 101 Implicit conversion class AmendedString(s: String) { def rot13 = new String(for (c <- s) yield rotC(c)) def rotC(c: Char) = (((c - 97) + 13) % 26 + 97).asInstanceOf[Char] } new AmendedString("yodude").rot13 implicit def string2amendedString(s: String) = new AmendedString(s) "yodude".rot13 31
  • 132. Scala 101 Implicit conversion class AmendedString(s: String) { def rot13 = new String(for (c <- s) yield rotC(c)) def rotC(c: Char) = (((c - 97) + 13) % 26 + 97).asInstanceOf[Char] } new AmendedString("yodude").rot13 implicit def string2amendedString(s: String) = new AmendedString(s) "yodude".rot13 lbqhqr 31
  • 133. Listeners class AmendedView(view: View) { def onClick(f: View => Unit) { view.setOnClickListener(new View.OnClickListener { override def onClick(v: View) = f(v) }) } } 32
  • 134. Listeners class AmendedView(view: View) { def onClick(f: View => Unit) { view.setOnClickListener(new View.OnClickListener { override def onClick(v: View) = f(v) }) } } 32
  • 135. Listeners class AmendedView(view: View) { def onClick(f: View => Unit) { view.setOnClickListener(new View.OnClickListener { override def onClick(v: View) = f(v) }) } } 32
  • 136. Listeners class AmendedView(view: View) { def onClick(f: View => Unit) { view.setOnClickListener(new View.OnClickListener { override def onClick(v: View) = f(v) }) } } 32
  • 137. Listeners class AmendedView(view: View) { def onClick(f: View => Unit) { view.setOnClickListener(new View.OnClickListener { override def onClick(v: View) = f(v) }) } } 32
  • 138. Listeners class AmendedView(view: View) { def onClick(f: View => Unit) { view.setOnClickListener(new View.OnClickListener { override def onClick(v: View) = f(v) }) } } implicit def view2AmendedView(view: View) = new AmendedView(view) 32
  • 139. Listeners class AmendedView(view: View) { def onClick(f: View => Unit) { view.setOnClickListener(new View.OnClickListener { override def onClick(v: View) = f(v) }) } } implicit def view2AmendedView(view: View) = new AmendedView(view) 32
  • 140. Listeners class AmendedView(view: View) { def onClick(f: View => Unit) { view.setOnClickListener(new View.OnClickListener { override def onClick(v: View) = f(v) }) } } implicit def view2AmendedView(view: View) = new AmendedView(view) 32
  • 141. Listeners class AmendedView(view: View) { def onClick(f: View => Unit) { view.setOnClickListener(new View.OnClickListener { override def onClick(v: View) = f(v) }) } } implicit def view2AmendedView(view: View) = new AmendedView(view) 32
  • 142. Listeners class AmendedView(view: View) { def onClick(f: View => Unit) { view.setOnClickListener(new View.OnClickListener { override def onClick(v: View) = f(v) }) } } implicit def view2AmendedView(view: View) = new AmendedView(view) 32
  • 143. Listeners class AmendedView(view: View) { def onClick(f: View => Unit) { view.setOnClickListener(new View.OnClickListener { override def onClick(v: View) = f(v) }) } } implicit def view2AmendedView(view: View) = new AmendedView(view) login.onClick { view => ... } 32
  • 144. Concurrency 33
  • 145. Responsiveness • Separate work and GUI GUI thread 34
  • 146. Responsiveness • Separate work and GUI GUI thread 34
  • 147. Responsiveness GUI thread worker Start worker 35
  • 148. Responsiveness new AsyncTask[Object, Void, Object]() { override def doInBackground(objects: Object*): Object = { ... do hard work } }.execute() 36
  • 149. Responsiveness new AsyncTask[Object, Void, Object]() { override def doInBackground(objects: Object*): Object = { ... do hard work } }.execute() 36
  • 150. Responsiveness new AsyncTask[Object, Void, Object]() { override def doInBackground(objects: Object*): Object = { ... do hard work } }.execute() 36
  • 151. Responsiveness new AsyncTask[Object, Void, Object]() { override def doInBackground(objects: Object*): Object = { ... do hard work } }.execute() 36
  • 152. Responsiveness new AsyncTask[Object, Void, Object]() { override def doInBackground(objects: Object*): Object = { ... do hard work } }.execute() 36
  • 153. Responsiveness new AsyncTask[Object, Void, Object]() { override def doInBackground(objects: Object*): Object = { ... do hard work } }.execute() 36
  • 154. Responsiveness GUI thread worker Start worker Update GUI 37
  • 155. Responsiveness runOnUiThread(new Runnable() { def run: Unit = { ... update GUI } }) 38
  • 156. Responsiveness runOnUiThread(new Runnable() { def run: Unit = { ... update GUI } }) 38
  • 157. Responsiveness runOnUiThread(new Runnable() { def run: Unit = { ... update GUI } }) 38
  • 158. Responsiveness runOnUiThread(new Runnable() { def run: Unit = { ... update GUI } }) 38
  • 159. Responsiveness runOnUiThread(new Runnable() { def run: Unit = { ... update GUI } }) 38
  • 160. Responsiveness new AsyncTask[Object, Void, Object]() { override def doInBackground(objects: Object*): Object = { ... do hard work runOnUiThread(new Runnable() { def run: Unit = { ... update GUI } }) } }.execute() 39
  • 161. Responsiveness new AsyncTask[Object, Void, Object]() { override def doInBackground(objects: Object*): Object = { ... do hard work runOnUiThread(new Runnable() { def run: Unit = { ... update GUI } }) } }.execute() 39
  • 162. Responsiveness new AsyncTask[Object, Void, Object]() { override def doInBackground(objects: Object*): Object = { ... do hard work runOnUiThread(new Runnable() { def run: Unit = { ... update GUI } }) } }.execute() 39
  • 163. Responsiveness new AsyncTask[Object, Void, Object]() { override def doInBackground(objects: Object*): Object = { ... do hard work runOnUiThread(new Runnable() { def run: Unit = { ... update GUI } }) } }.execute() 39
  • 164. Responsiveness new AsyncTask[Object, Void, Object]() { override def doInBackground(objects: Object*): Object = { ... do hard work runOnUiThread(new Runnable() { def run: Unit = { ... update GUI } }) } }.execute() 39
  • 165. Responsiveness new AsyncTask[Object, Void, Object]() { override def doInBackground(objects: Object*): Object = { ... do hard work runOnUiThread(new Runnable() { def run: Unit = { ... update GUI } }) } }.execute() 39
  • 166. Responsiveness new AsyncTask[Object, Void, Object]() { override def doInBackground(objects: Object*): Object = { ... do hard work runOnUiThread(new Runnable() { def run: Unit = { ... update GUI } }) } }.execute() 39
  • 167. Responsiveness new AsyncTask[Object, Void, Object]() { override def doInBackground(objects: Object*): Object = { ... do hard work runOnUiThread(new Runnable() { def run: Unit = { ... update GUI } }) } }.execute() 39
  • 168. Responsiveness new AsyncTask[Object, Void, Object]() { override def doInBackground(objects: Object*): Object = { ... do hard work runOnUiThread(new Runnable() { def run: Unit = { ... update GUI } }) } }.execute() 39
  • 169. Responsiveness new AsyncTask[Object, Void, Object]() { override def doInBackground(objects: Object*): Object = { ... do hard work onUiThread { ... update GUI } } }.execute() 40
  • 170. Responsiveness asyncTask { ... do hard work onUiThread { ... update GUI } } 41
  • 171. Further 42
  • 172. Actors Organizing with asynchronous message passing 43
  • 173. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } 44
  • 174. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } 44
  • 175. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } 44
  • 176. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } 44
  • 177. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } 44
  • 178. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } 44
  • 179. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } 44
  • 180. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } 44
  • 181. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } 44
  • 182. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } 44
  • 183. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } 44
  • 184. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } 44
  • 185. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } 44
  • 186. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } 44
  • 187. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } MyActor ! "Yo dude" 44
  • 188. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } MyActor ! "Yo dude" 44
  • 189. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } MyActor ! "Yo dude" 44
  • 190. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } MyActor ! "Yo dude" 44
  • 191. Scala 101 Actors object MyActor extends Actor { def act { loop { react { case msg:String => println(msg) case other => println("Say what") } } } start } MyActor ! "Yo dude" Yo dude 44
  • 192. Actors GUI Connection Model Factory ViewStack href, (xml, error) httperror, none xml, (model, error) xmlerror, none model, (model) model, none 45
  • 193. Actors GUI Connection Model Factory ViewStack href, (xml, error) httperror, none xml, (model, error) xmlerror, none model, (model) model, none 45
  • 194. Actors GUI Connection Model Factory ViewStack href, (xml, error) httperror, none xml, (model, error) xmlerror, none model, (model) model, none 45
  • 195. Actors GUI Connection Model Factory ViewStack href, (xml, error) httperror, none xml, (model, error) xmlerror, none model, (model) model, none 45
  • 196. Actors GUI Connection Model Factory ViewStack href, (xml, error) httperror, none xml, (model, error) xmlerror, none model, (model) model, none 45
  • 197. Actors GUI Connection Model Factory ViewStack href, (xml, error) httperror, none xml, (model, error) xmlerror, none model, (model) model, none 45
  • 198. Actors GUI Connection Model Factory ViewStack href, (xml, error) httperror, none xml, (model, error) xmlerror, none model, (model) model, none 45
  • 199. Actors GUI Connection Model Factory ViewStack href, (xml, error) httperror, none xml, (model, error) xmlerror, none model, (model) model, none 45
  • 200. Actors GUI Connection Model Factory ViewStack href, (xml, error) httperror, none xml, (model, error) xmlerror, none model, (model) model, none 45
  • 201. Actors GUI Connection Model Factory ViewStack href, (xml, error) httperror, none xml, (model, error) xmlerror, none model, (model) model, none 45
  • 202. Actors GUI Connection Model Factory ViewStack href, (xml, error) httperror, none xml, (model, error) xmlerror, none model, (model) model, none 45
  • 203. Actors GUI Connection Model Factory ViewStack href, (xml, error) httperror, none xml, (model, error) xmlerror, none model, (model) model, none 45
  • 204. Actors GUI Connection Model Factory ViewStack href, (xml, error) httperror, none xml, (model, error) xmlerror, none model, (model) model, none 45
  • 205. Actors GUI Connection Model Factory ViewStack href, (xml, error) httperror, none xml, (model, error) xmlerror, none model, (model) model, none 45
  • 206. Actors GUI Connection Model Factory ViewStack href, (xml, error) httperror, none xml, (model, error) xmlerror, none model, (model) model, none 45
  • 207. Actors case class Routing(success: Option[Actor], failure: Option[Actor]) case class HttpRequestMsg(href: URL, routing: Routing) 46
  • 208. Actors case class Routing(success: Option[Actor], failure: Option[Actor]) case class HttpRequestMsg(href: URL, routing: Routing) 46
  • 209. Actors case class Routing(success: Option[Actor], failure: Option[Actor]) case class HttpRequestMsg(href: URL, routing: Routing) 46
  • 210. Actors case class Routing(success: Option[Actor], failure: Option[Actor]) case class HttpRequestMsg(href: URL, routing: Routing) 46
  • 211. Actors case class Routing(success: Option[Actor], failure: Option[Actor]) case class HttpRequestMsg(href: URL, routing: Routing) 46
  • 212. Actors case class Routing(success: Option[Actor], failure: Option[Actor]) case class HttpRequestMsg(href: URL, routing: Routing) 46
  • 213. Actors case class Routing(success: Option[Actor], failure: Option[Actor]) case class HttpRequestMsg(href: URL, routing: Routing) 46
  • 214. Actors case class Routing(success: Option[Actor], failure: Option[Actor]) case class HttpRequestMsg(href: URL, routing: Routing) 46
  • 215. Actors case class Routing(success: Option[Actor], failure: Option[Actor]) case class HttpRequestMsg(href: URL, routing: Routing) 46
  • 216. Actors case class Routing(success: Option[Actor], failure: Option[Actor]) case class HttpRequestMsg(href: URL, routing: Routing) 46
  • 217. Actors case class Routing(success: Option[Actor], failure: Option[Actor]) case class HttpRequestMsg(href: URL, routing: Routing) 46
  • 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
  • 244. Androids on Scala Fini @thoraageeldby 48