Slide 1

Slide 1 text

SCALA VS KOTLIN Javi Pacheco @javielinux Antonio Leiva @lime_cl

Slide 2

Slide 2 text

Introduction

Slide 3

Slide 3 text

• JVM based • Functional Language & OOP • Immutability emphasis • Purity & Effects • High-order functions • Flexible syntax, create constructs, infix support Scala is LOVE

Slide 4

Slide 4 text

Who’s using Scala?

Slide 5

Slide 5 text

47 Degrees Projects Scala Days Scala API Demos Translate Bubble

Slide 6

Slide 6 text

Introduction

Slide 7

Slide 7 text

• JVM based • Object-oriented functional language • Created by JetBrains (IntelliJ, Android Studio) • Simple,lightweight, interoperable

Slide 8

Slide 8 text

• Compiled to Java bytecode • Open source • Kotlin 1.0 Beta 3

Slide 9

Slide 9 text

Who’s using Kotlin?

Slide 10

Slide 10 text

Who’s using Kotlin? BusRadar Omni Reedy Wizbii

Slide 11

Slide 11 text

Hello World!

Slide 12

Slide 12 text

1. Install plugin

Slide 13

Slide 13 text

1. Install plugin 2. Create a Kotlin class

Slide 14

Slide 14 text

1. Install plugin 2. Create a Kotlin class 3. Use “Configure Kotlin in Project”

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

1. Download SBT and install it Installation

Slide 17

Slide 17 text

1. Download SBT and install it 2. Install Scala Plugin in IntelliJ Installation

Slide 18

Slide 18 text

1. Download SBT and install it 2. Install Scala Plugin in IntelliJ 3. Configure your project > sbt Installation

Slide 19

Slide 19 text

Null handling

Slide 20

Slide 20 text

val maybeArtist: Option[Artist] = getArtist()
 maybeArtist map { artist => artist.print() } Some(artist) None artist.print() Nothing Option Monad

Slide 21

Slide 21 text

val artist: Artist = maybeArtist getOrElse(defaultArtist) val maybeArtist: Option[Artist] = Option(getArtist()) Providing a Default Value Java Integration

Slide 22

Slide 22 text

var artist: Artist? = null
 artist.print() var artist: Artist? = null
 artist?.print() Won’t compile Won’t do anything if (artist != null) {
 artist.print()
 } Smart cast var artist: Artist? = null
 artist!!.print() It crashes!

Slide 23

Slide 23 text

UI and Animations

Slide 24

Slide 24 text

verticalLayout {
 val name = editText()
 button("Say Hello") {
 onClick { toast("Hello, ${name.text}!") }
 }
 } Anko

Slide 25

Slide 25 text

Kotlin Android Extensions Import synthetic properties: import kotlinx.android.synthetic.activity_main.* Just use them: override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState) setContentView(R.id.main)
 } recycler.layoutManager = GridLayoutManager(this, 2)
 recycler.adapter = ContactsAdapter(contacts)


Slide 26

Slide 26 text

• DSL focused to GUI • Intensive use of Macros • Brings the Functional Programming on Ui editText <~ text("foo") <~~ fadeIn <~ enable Macroid library https://github.com/47deg/functional-views-android

Slide 27

Slide 27 text

Background tasks

Slide 28

Slide 28 text

asyncArtist map { artist => artist.print() } Future Monad val asyncArtist: Future[Artist] = getAsyncArtist val asyncFilm: Future[Film] = getAsyncLastFilm(“Barroso”)

Slide 29

Slide 29 text

For Comprehensions val asyncFilm = for { artist <- getAsyncArtist film <- getAsyncLastFilm(artist.name) } yield (film) asyncFilm map (film => film.print())

Slide 30

Slide 30 text

Anko async {
 val contacts = GetContactsCommand().execute(ctx)
 uiThread {
 recycler.adapter = ContactsAdapter(contacts)
 }
 }

Slide 31

Slide 31 text

Kovenant (promises) async {
 //some (long running) operation, or just:
 1 + 1
 } then {
 i -> "result: $i"
 } successUi {
 msg -> println(msg)
 }

Slide 32

Slide 32 text

Data persistence

Slide 33

Slide 33 text

var myPref: Long by Preference(this, "name", 0) Property delegation val prefValue = myPref
 myPref = 20

Slide 34

Slide 34 text

Anko ManagedSQLiteOpenHelper dbHelper.use {
 select("TABLE_NAME").where("_id = {id}", "id" to 20)
 } db.createTable("TABLE_NAME", true,
 "_id" to INTEGER + PRIMARY_KEY,
 "name" to TEXT) parseList / parseOpt / classParser…

Slide 35

Slide 35 text

slick -> http://slick.typesafe.com/ doobie -> https://github.com/tpolecat/doobie Pure functional JDBC layer for Scala mvessel -> https://github.com/47deg/mvessel JDBC driver written in Scala The main goal is to allow the use of ORMs in Android

Slide 36

Slide 36 text

val xa = DriverManagerTransactor[IO]( "org.postgresql.Driver", "jdbc:postgresql:world", "postgres", "" ) case class Country(code: String, name: String, population: Long) def find(n: String): ConnectionIO[Option[Country]] = sql"select code, name from country where name = $n”.query[Country].option find("France").transact(xa).unsafePerformIO Some(Country(FRA, France)) Doobie Sample

Slide 37

Slide 37 text

Testing

Slide 38

Slide 38 text

Unit Testing specs2 -> https://etorreborre.github.io/specs2/ scalacheck -> https://www.scalacheck.org/

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

JUnit Interoperability -> All testing libraries available Hamkrest -> https://github.com/npryce/hamkrest Mockito-kt -> https://github.com/paslavsky/mockito-kt

Slide 41

Slide 41 text

Spek

Slide 42

Slide 42 text

Multiple inheritance

Slide 43

Slide 43 text

Interfaces • Can contain code (but not state) interface ToolbarManager {
 
 val toolbar: Toolbar
 
 fun initToolbar() {
 toolbar.inflateMenu(R.menu.menu_main)
 toolbar.setOnMenuItemClickListener {
 when (it.itemId) {
 R.id.action_settings -> App.instance.toast("Settings")
 else -> App.instance.toast("Unknown option")
 }
 true
 }
 }
 }

Slide 44

Slide 44 text

Interfaces class MainActivity : AppCompatActivity(), ToolbarManager {
 
 override val toolbar by lazy { find(R.id.toolbar) }
 
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_main)
 initToolbar()
 ...
 }
 }


Slide 45

Slide 45 text

• Fundamental unit of code reuse in Scala • A class can mix in any number • Order matters Traits & self types

Slide 46

Slide 46 text

class MyActivity extend Activity with PresentationTrait { def onCreate() = initUi() } trait PresentationTrait { self: Activity => def initUi() = getApplicationContext } Example

Slide 47

Slide 47 text

Dependency injection

Slide 48

Slide 48 text

Cake Pattern • Dependencies between components • Traits & Self types macwire -> https://github.com/adamw/macwire scaldi -> http://scaldi.org/ Libraries Implicit • Dependencies using implicit

Slide 49

Slide 49 text

Simple injection can be done without libraries: - Interface delegation - Default values for arguments Several libraries - Dagger 2 (https://github.com/google/dagger) - Kodein (https://github.com/SalomonBrys/Kodein) - Injekt (https://github.com/kohesive/injekt)

Slide 50

Slide 50 text

Delegate handling

Slide 51

Slide 51 text

val f: (Int, String) -> String = { i, s -> "$s $i" } 
 val f = { i: Int, s: String -> "$s $i" } fun myFun(listener: (View) -> Unit) {
 ...
 listener(view)
 } Variables Function parameters

Slide 52

Slide 52 text

Higher-order function • Takes one or more functions as arguments • Returns a function as its result val f1: (Int) => String = (myInt) => myInt.toString def myFunc(f: (Int) => String) = { println(f(2)) }

Slide 53

Slide 53 text

Pattern matching

Slide 54

Slide 54 text

def toYesOrNo(choice: Int): String = choice match { case 1 => "yes" case 0 => "no" case _ => "error" } Traditional approach def get(animal: Animal): String = animal match { case cat: Cat => “I’m a cat: ” + cat.toString case dog: Dog => “I’m a dog: ” + dog.toString case _ => “Other animal" } Typed pattern

Slide 55

Slide 55 text

case class Developer(name: String, lang: String) def developer(dev: Developer): String = dev match { case Developer(_, “scala”) => “Good Dev" case Developer(“Jorge Barroso”, _) => “The best" case _ => “Java Developers" } Cases Classes def developer(dev: Developer): String = dev match { case Developer(_, “scala”) => “Good Dev" case Developer(name, _) if name.contains(“Jorge”) => “The best" case _ => “Java Developers" } If statements

Slide 56

Slide 56 text

No pattern matching, but powerful “when” val cost = when(x) {
 in 1..10 -> "cheap"
 in 10..100 -> "regular"
 in 100..1000 -> "expensive"
 in specialValues -> "special value!"
 else -> "not rated"
 }

Slide 57

Slide 57 text

val res = when {
 x in 1..10 -> "cheap"
 s.contains("hello") -> "it's a welcome!"
 v is ViewGroup -> "child count: ${v.getChildCount()}"
 else -> ""
 }

Slide 58

Slide 58 text

Learning curve from Java

Slide 59

Slide 59 text

• Really fast -> many similar concepts • Interoperability • Great official reference and Koans

Slide 60

Slide 60 text

No content

Slide 61

Slide 61 text

http://scala-exercises.47deg.com/

Slide 62

Slide 62 text

Debugger

Slide 63

Slide 63 text

Debugger same as Java • Breakpoints • Step debugging • Watches • … • All inside Android Studio

Slide 64

Slide 64 text

Debugger same as Java • Breakpoints • Step debugging • Watches • … • All inside Android Studio

Slide 65

Slide 65 text

Compilation times

Slide 66

Slide 66 text

http://antonioleiva.com/plaid-kotlin-1/

Slide 67

Slide 67 text

• Slower (Scala Compiler + Proguard) • Size matters (+ ~2.8 M) Compile Take your time to setup your SBT • Incremental compiler • Continuous build and test