Save 37% off PRO during our Black Friday Sale! »

Getting to 100% Kotlin: A practical guide

1b4a6c2e7bafdb5c945865dac35a9eb3?s=47 Dan Kim
September 25, 2017

Getting to 100% Kotlin: A practical guide

A lot of teams are super excited by Kotlin and are ready to go all-in with it. But while exciting, it can also be stressful — learning a brand new language while converting old code and writing new features, all at the same time? How does a team get there as smoothly as possible?

We’re here to help! At Basecamp we’ve worked hard to make our codebase 100% Kotlin over the course of the last year. We learned a lot and want to share a roadmap of how you can get there too.

If you're just starting out with Kotlin but can already see its potential, this talk is for you. We’ll share our best overarching strategies and tips based on a year of real-world shipping — how to get started, how to keep moving forward, and pitfalls to keep an eye out for.

No theory here, this is all based on our actual experiences getting to 100% Kotlin.

(Talk given at Android Summit 2017 on 8/24/17 and Droidcon NYC 2017 on 9/25/17)

1b4a6c2e7bafdb5c945865dac35a9eb3?s=128

Dan Kim

September 25, 2017
Tweet

Transcript

  1. Getting to 100% Kotlin: A practical guide dan@basecamp.com @dankim

  2. Why was Kotlin important to us?

  3. It made me happy!

  4. Running headfirst into the unknown

  5. Learn the language (and ship)

  6. Convert our backlog of Java (and ship)

  7. What pitfalls should we watch out for?

  8. ✅ Practical, low-stress strategies

  9. Get real with production code

  10. Start with small conversions

  11. No tests!

  12. Getting excited is important!

  13. Start with small conversions

  14. Start with small conversions ✅ POJOs / Models

  15. Start with small conversions ✅ POJOs / Models ✅ Util

    methods
  16. Start with small conversions ✅ Adapters ✅ POJOs / Models

    ✅ Util methods
  17. Start with small conversions ✅ Adapters ✅ POJOs / Models

    ✅ Util methods Entire Retrofit implementation
  18. Forget about being perfect

  19. ✌Idiomatic Kotlin✌

  20. Don’t get too caught up in it

  21. Find yourself in some serious rabbit holes

  22. fun processAccounts(accounts: List<Account>?) {
 for (account in accounts!!) {
 if

    (account.active) {
 ...
 } else if (account.trial) {
 ...
 } else {
 ...
 }
 }
 }
  23. fun processAccounts(accounts: List<Account>?) {
 for (account in accounts!!) {
 if

    (account.active) {
 ...
 } else if (account.trial) {
 ...
 } else {
 ...
 }
 }
 }
  24. fun processAccounts(accounts: List<Account>?) {
 for (account in accounts!!) {
 if

    (account.active) {
 ...
 } else if (account.trial) {
 ...
 } else {
 ...
 }
 }
 }
  25. fun processAccounts(accounts: List<Account>?) {
 for (account in accounts!!) {
 if

    (account.active) {
 ...
 } else if (account.trial) {
 ...
 } else {
 ...
 }
 }
 }
  26. fun processAccounts(accounts: List<Account>?) {
 for (account in accounts!!) {
 if

    (account.active) {
 ...
 } else if (account.trial) {
 ...
 } else {
 ...
 }
 }
 }
  27. fun processAccounts(accounts: List<Account>?) {
 for (account in accounts!!) {
 if

    (account.active) {
 ...
 } else if (account.trial) {
 ...
 } else {
 ...
 }
 }
 }
  28. fun processAccounts(accounts: List<Account>?) {
 for (account in accounts!!) {
 if

    (account.active) {
 ...
 } else if (account.trial) {
 ...
 } else {
 ...
 }
 }
 }
  29. Find a few key concepts that click *for you*

  30. Find a few key concepts that click *for you*

  31. Find a few key concepts that click *for you* ✅

    Flow control
  32. Find a few key concepts that click *for you* ✅

    Flow control ✅ Collections
  33. Find a few key concepts that click *for you* ✅

    Flow control ✅ Collections ✅ Extension functions
  34. The auto converter is your friend

  35. Side by side learning

  36. You’re only ~60% done (don’t ship it)

  37. Take it to the finish line

  38. ❄ Use cool downs for Kotlin

  39. Leave the campsite cleaner than you found it

  40. Things might get ugly

  41. Curb your enthusiasm

  42. None
  43. fun success(inboxItems: InboxItems) = with(inboxItems.withoutPings()) { doAsync { CachePrefs.setInboxCache(context, this@with)

    } }
  44. fun success(inboxItems: InboxItems) = with(inboxItems.withoutPings()) { doAsync { CachePrefs.setInboxCache(context, this@with)

    } }
  45. fun success(inboxItems: InboxItems) = with(inboxItems.withoutPings()) { doAsync { CachePrefs.setInboxCache(context, this@with)

    } }
  46. fun success(inboxItems: InboxItems) = with(inboxItems.withoutPings()) { doAsync { CachePrefs.setInboxCache(context, this@with)

    } }
  47. fun success(inboxItems: InboxItems) = with(inboxItems.withoutPings()) { doAsync { CachePrefs.setInboxCache(context, this@with)

    } }
  48. fun success(inboxItems: InboxItems) {
 val items = inboxItems.filterNot { ...

    } 
 doAsync { CachePrefs.setInboxCache(context, items) }
 }
  49. fun success(inboxItems: InboxItems) {
 val items = inboxItems.filterNot { ...

    } 
 doAsync { CachePrefs.setInboxCache(context, items) }
 }
  50. fun success(inboxItems: InboxItems) {
 val items = inboxItems.filterNot { ...

    } 
 doAsync { CachePrefs.setInboxCache(context, items) }
 }
  51. fun success(inboxItems: InboxItems) {
 val items = inboxItems.filterNot { ...

    } 
 doAsync { CachePrefs.setInboxCache(context, items) }
 }
  52. fun success(inboxItems: InboxItems) {
 val items = inboxItems.filterNot { ...

    } 
 doAsync { CachePrefs.setInboxCache(context, items) }
 }
  53. Keep an eye on your code organization

  54. Don’t forget about your customers

  55. Programmer happiness is crucial!

  56. Your customers don’t care

  57. Take your time

  58. 430 days!

  59. It’s just a number

  60. Thank you! dan@basecamp.com @dankim