Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Level up in Kotlin - mDevCamp 2019

Level up in Kotlin - mDevCamp 2019

pahill

May 31, 2019
Tweet

More Decks by pahill

Other Decks in Programming

Transcript

  1. I am Pamela Hill Android Engineer - Luno You can

    find me here: • Twitter: @pamelaahill • Blog: www.pamelaahill.com Hello! ! 2
  2. ! 3

  3. Coroutines • Like lightweight threads • Run on a shared

    pool of threads, one thread can run many coroutines ! 7
  4. Suspendable computation Function that can suspend its computation at some

    point and resume later on, without blocking the thread ! 8
  5. Scope Coroutine Launches Coroutine Builder Originates from Suspending Function Runs

    Dispatcher Specifies Controls thread Coroutine Context Runs in
  6. Suspending function • Suspend and resume without blocking the thread

    • Marked with suspend keyword in function signature ! 12
  7. Scope Coroutine Launches Coroutine Builder Originates from Suspending Function Runs

    Dispatcher Specifies Controls thread Coroutine Context Runs in
  8. ! 18 suspend fun launchSpaceShuttle(){...}
 suspend fun flyToDestination(){...}
 suspend fun

    dockOnSpaceStation(){...} val job = launch {
 println(“10,9,8 ... Ignition!”)
 launchSpaceShuttle()
 flyToDestination()
 dockOnSpaceStation()
 println(“Mission complete.”)
 } println("What were we doing again?")
  9. ! 20 suspend fun launchSpaceShuttle(){..}
 suspend fun flyToDestination(){...}
 suspend fun

    dockOnSpaceStation(){...}
 
 val job = runBlocking {
 println(“10,9,8 ... Ignition!”)
 launchSpaceShuttle()
 flyToDestination()
 dockOnSpaceStation()
 println(“Mission complete.”)
 }
 println("That was amazing!")
  10. ! 22 suspend fun checkFlightPath(): FlightPath {...}
 suspend fun checkCrewHealth():

    CrewHealth {...}
 fun reportToMissionControl(flightPath: FlightPath, crewHealth: CrewHealth){...}

  11. ! 23 suspend fun checkFlightPath(): FlightPath {...}
 suspend fun checkCrewHealth():

    CrewHealth {...}
 fun reportToMissionControl(flightPath: FlightPath, crewHealth: CrewHealth){...} val job = launch {
 val flightPath = async {checkFlightPath()}
 val crewHealth = async {checkCrewHealth()}
 reportToMissionControl(flightPath.await(), crewHealth.await()) }

  12. Coroutines - key takeaways • Coroutines are like lightweight threads

    • Suspendable computations suspend and resume - without blocking the thread • Coroutines are performant, readable, and compatible with JetPack • launch, runBlocking, async are examples of coroutine builders ! 24
  13. What conventions are there? • Arithmetic operators: binary (+, -,

    *, /, %) and 
 unary (+, -, !, ++, —) • Comparison operators: (<, <=, >, >=) • Collection and range-related: ([], .., in) • Destructuring declarations • Delegates ! 27
  14. ! 28 class Point(private val x: Double, private val y:

    Double){...} val spaceStationPosition = Point(100.0, 100.0)
 val spaceShuttlePosition = Point(10.0, 10.0)
 
 val distance = spaceStationPosition - spaceShuttlePosition
  15. ! 30 class Point(private val x: Double, private val y:

    Double) { operator fun minus(other: Point): Double { //Pythagorian algorithm - not important here! return sqrt(pow(x - other.x, 2.0) + pow(y - other.y, 2.0)) } }
  16. ! 31 class Point(private val x: Double, private val y:

    Double){...} val spaceStationPosition = Point(100.0, 100.0)
 val spaceShuttlePosition = Point(10.0, 10.0)
 
 val dockable = spaceStationPosition == spaceShuttlePosition
  17. ! 32 class Point(private val x: Double, private val y:

    Double){ override operator fun equals(other: Any?): Boolean { if (this === other) return true if (other !is Point) return false return (abs(x - other.x) < 0.1) && (abs(y - other.y) < 0.1) } }
  18. ! 33 class Point(private val x: Double, private val y:

    Double){...} val spaceStationPosition = Point(100.0, 100.0)
 val spaceShuttlePosition = Point(10.0, 10.0)
 
 spaceStationPosition > spaceShuttlePosition
  19. ! 34 class Point(private val x: Double, private val y:

    Double){ operator fun compareTo(point: Point): Int { val origin = Point(0.0,0.0) val difference = (this - origin) - (point - origin) return difference.roundToInt() } }
  20. ! 35 class Point(val x: Double, val y: Double){...} class

    FlightPath(val origin: Point, val destination: Point) {...} val spaceStationPosition = Point(100.0, 100.0) val spaceShuttlePosition = Point(10.0, 10.0) val earth = Point(0.0, 0.0) val flightPath = FlightPath(earth, spaceStationPosition) val onTrack = spaceShuttlePosition in flightPath
  21. ! 36 class FlightPath(val origin: Point, val destination: Point) {

    operator fun contains(point: Point): Boolean{ return point.x == point.y } }
  22. ! 37 class Point(val x: Double, val y: Double){...} class

    FlightPath(val origin: Point, val destination: Point) {...} val spaceStationPosition = Point(100.0, 100.0) val spaceShuttlePosition = Point(10.0, 10.0) val earth = Point(0.0, 0.0) val flightPath = FlightPath(earth, spaceStationPosition) for(checkpoints in flightPath){ println(checkpoints) }
  23. ! 38 class FlightPath(val origin: Point, val destination: Point) {

    operator fun iterator(): Iterator<Point> { return object : Iterator<Point> { var currentPoint = origin override fun hasNext(): Boolean {…} override fun next(): Point {…} } } }
  24. ! 39 class Point(private val x: Double, private val y:

    Double){...} val spaceStationPosition = Point(100.0, 100.0) 
 val (x, y) = spaceStationPosition
  25. ! 40 class Point(private val x: Double, private val y:

    Double) { operator fun component1() = x operator fun component2() = y } 

  26. Conventions - key takeaways • Conventions are functions with specific

    names • Conventions are concise, readable, and maintainable • Consider understandability - use well-known concepts, and check with others using code reviews ! 42
  27. General-purpose language A general-purpose language solves any problem that can

    be solved by a computer A general-purpose language is imperative, specifying the operations to solve the problem What is a DSL? Domain-specific language A domain-specific language focuses on solving problems in a specific domain A domain-specific language is declarative, describing the required result ! 44
  28. External DSL Unrestricted in terms of how it expresses itself

    Requires string concatenation and parsing What is an internal DSL? Internal DSL Restricted by the syntax of a general purpose language No concatenation or parsing necessary ! 45
  29. Why is Kotlin great for constructing DSLs? • Optional semicolon

    - removes syntactic noise • Dropping . and ( ) by infixing functions
 str should startsWith("Space") is more readable than assertTrue(str.startsWith(“Space")) • Extension functions - makes existing code more fluent • No ( ) required for last lambda argument - removes syntactic noise • Lambdas with receivers • Invoke convention ! 47
  30. DSLs - key takeaways • DSLs are focused on describing

    only solutions to problems for a specific domain • DSLs are concise, readable, and maintainable • Language features like lambdas with receivers support the creation of readable DSLs ! 51
  31. Credits Special thanks to all the people who made and

    released these awesome resources for free: ‒ Presentation template by SlidesCarnival ‒ Photographs by Unsplash ! 55