Juraj Mičko
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Kotlin Kotlin is something programmers never forget about. I hadn’t heard of Kotlin until 17 June this year. Since then, I have used almost no other language. The story started a few weeks before that date. By a coincidence, I was in contact with Lenka Kucerova, passionate CEO & Co-founder of StarLift.org, who sent me a link to a hackathon that would take place in Prague. I didn’t know much about hackathons, but as always, I wanted at least to make an attempt to attend. My friends and I built a nice-looking PDF application that we sent them. Luckily we got in, the hackathon going to be our first experience of its kind. How does it all relate to Kotlin? Because at [HackPrague](hackprague.com), the hackathon, there was a sponsored prize called *Let's Program in Kotlin!* encouraging us to utilize the new-born language. Honestly, my first impression was: What a terrible language must it be that they need to reward people for using it? From what I heard, it’s trying to be innovative, while interoperable with good old Java. Of course, we had no time learning the new language during the hurried event full of hustle. Instead, we opted for *The most innovative UX for mobile event discovery* prize. Eventually, we got 2nd place and won the prize. One week later, motivated, we attended another hackathon in Prague. The second day of coding we realized that our concept is not a winning one. We wanted to include a snippet of innovation in our project that would at least make us feel we have something that others do not. I really don’t know why, but my following commit on Github included a few classes written in Kotlin. (Side note: It didn’t help to succeed.) What is important, I had a slight scent of what Kotlin may be and that perhaps it’s not as bad as I thought at first. My following weekend wasn’t as full as my weekends tend to be and I had some time I could invest into learning more about Kotlin, so I opened the Kotlin language reference and started reading. It turned out to be a life-changing weekend (from the programmer’s part of life :)). The more I read, the more strongly I was captivated. Let’s dive into it. I’ll briefly present only a few features I like the most. The purpose of the article is to motivate you to learn Kotlin, definitely not to serve as a language reference. ## Not a boring language Java programmers benefit a lot from having everything declared with a type that is known during compile time. The drawback is writing a *boring* parts code, i.e. things a monkey could write being given only the line of code, without even knowing the context. ```java String s = "Hello World!"; BufferedStreamReader bsr = new BufferedStreamReader(stream); ``` In Kotlin, the same can be achieved without boring code. Kotlin developers consider type declarations, `new` keyword and semicolons as boring, hence the equivalent in Kotlin is ```kotlin val s = "Hello World!" val bsr = BufferedStreamReader(stream) ``` Of course, you can override the inferred type, or provide it in case it can't be inferred. ```kotlin val pet: Animal = Dog() val pet2 = Dog() as Animal // downcasting or upcasting ``` Whenever you specify `val`, the variable is final. For rewritable variables use `var`. ## Null safety In Kotlin, every type either can hold null values (`String?`) or can’t (`String`). Assign a possibly null value to a variable not accepting null values and the compiler will complain. Neither invoking a method on a nullable type is permitted. So how do we sort it out? All the following examples produce the same result. ```kotlin // This is basically what one would write in Java style fun whoIs(user: User?): String? { if (user != null) { return user.name } else { return null } } // But the `if` block is also an expression in Kotlin fun whoIs(user: User?): String? { return if (user != null) user.name else null } // The ?. operator will invoke the method only if the object is not null, // otherwise the whole expression evaluates to null fun whoIs(user: User?): String? { return user?.name } // Finally, using a short syntax of methods (the inferred return type is still String?) fun whoIs(user: User?) = user?.name // We can supply default values with the Elvis operator ?: that will evaluate // to the right side if and only if the expression on the left is null // Note that in this particular case, the compiler infers the return type to by non-null `String` fun whoIs(user: User?) = user?.name ?: "no one" ``` ## Extension functions Some languages support extending existing classes by defining their members (fields or methods) without changing the class definitions at all. Libraries tend to define many extension functions on common objects and the methods eventually collide since a class can't have two methods with the same signature. However, Kotlin has everything covered. First, it's important to understand how Kotlin's extension functions work and how they can be compiled to Java. Consider the following definition: ```kotlin fun Boolean.thenRun(block: () -> Unit): Boolean { if (this) { block.invoke() } return this } ``` The method has one argument, a lambda without parameters that returns `Unit` (equivalent to `void` in Java). If the receiver of the function (i.e. the boolean value) is true, the lambda is invoked. After that, the original boolean value is returned. Let's save the code to `MyFile.kt`, compile it and decompile the resulting `MyFileKt.class` back to Java. The output is roughly the following (I removed unimportant parts): ```java public final class MyFileKt { public static final boolean thenRun(boolean $receiver, @NotNull Function0 block) { Intrinsics.checkParameterIsNotNull(block, "block"); if($receiver) { block.invoke(); } return $receiver; } } ``` As we can see, Kotlin tackles the problem by defining a public static method instead that takes the boolean value as its first argument. Amazing! We can have as many libraries as we want and member collision will not occur since you always need to import the right one. Few notes here: + Kotlin's type `Boolean` changed to `boolean` as the compiler knows that it won't hold null values + We defined the method directly in the file, not as a class member, however, Kotlin supports also extension functions as class members. + As you may have noticed, things in Kotlin are usually `public` and `final` unless other is specified. Now consider what use may this function have. Look at the following logic written in Java: ```java public class MyClass { ... public boolean doSomething() { boolean isSuccess = doTheTask(); // returns true on success if (isSuccess) { System.out.println("OK"); } return isSuccess; } } ``` Pretty simple. We run a task, store its result. If positive, we run another block of code (printing to console in this case). Then we return the original value. Now look at what Kotlin offers: ```kotlin fun doSomething(): Boolean { return doTheTask().thenRun { println("OK") } } // or even better fun doSomething() = doTheTask().thenRun { println("OK") } ``` Not only is the code much shorter, we completely got rid of a variable! Note that if the last argument of a function is a lambda, you can put it out of parentheses, and you can omit them if the parentheses are empty. Kotlin has many extension functions built in that you don't have to write. ## No boilerplate code Code in Kotlin: ```kotlin data class Human(var name: String?, private val birth: Date) : Mammal(birth) ``` Code decompiled to Java is the following. It's longer, I removed more uninteresting parts. ```java public final class Human extends Mammal { @Nullable private String name; private final Date birth; public Human(@Nullable String name, @NotNull Date birth) { Intrinsics.checkParameterIsNotNull(birth, "birth"); super(birth); this.name = name; this.birth = birth; } @Nullable public final String getName() { return this.name; } public final void setName(@Nullable String var1) { this.name = var1; } @Nullable public final String component1() { return this.name; } private final Date component2() { return this.birth; } @NotNull public final Human copy(@Nullable String name, @NotNull Date birth) { Intrinsics.checkParameterIsNotNull(birth, "birth"); return new Human(name, birth); } public String toString() { return "Human(name=" + this.name + ", birth=" + this.birth + ")"; } public int hashCode() { return (this.name != null?this.name.hashCode():0) * 31 + (this.birth != null?this.birth.hashCode():0); } public boolean equals(Object var1) { if(this != var1) { if(var1 instanceof Human) { Human var2 = (Human)var1; if(Intrinsics.areEqual(this.name, var2.name) && Intrinsics.areEqual(this.birth, var2.birth)) { return true; } } return false; } else { return true; } } } ``` I guess you get my point that Kotlin is concise. Much more concise. ## Properties & Delegated properties Whenever there are `getSomething()` and `setSomething(value)` methods, Kotlin considers it to be a property and you can access it just by writing `obj.something` and `obj.something = value`. When you create a class with a property (such as the following example), it is compiled to a class with private property with appropriate getters and setters. This is exactly what happened in the previous example. Of course one can modify everything. ```kotlin open class HeyWorld(val abc: String) { // not final class // `abc` is a constructor argument and an immutable property with a setter var foo = "bar" // public getter and setter private val now = Date() // private getter and no setter (because of `val`) protected var amount: Int? = null // protected property initialized to null // here we define custom getter; field is a special keyword in this scope get() = field ?: 0 // returns the value if not null, otherwise returns 0 private set // setter is private open var abracadabra: Boolean? = true // not final field (unlike the rest) set(value) { // value is of type Boolean? field = if (value != null) // but we negate it as it has been smart-casted to Boolean !value else null // the same could be achieved by writing // field = value?.not() } } ``` A delegated property means that you delegate the responsibility of accepting and providing value to someone else. ```kotlin class Example { var p: String by Delegate() } ``` The `Delegate` object must have some `getValue` and `setValue` methods defined, but let's focus on the usability again. ```kotlin // lazy evaluation val lazyValue by lazy { print("The property is being evaluated for the first time!") "Hello World!" } // managing more properties by one object class Person(val map: MutableMap<String, Any?>) { var name: String by map var age: Int by map } ``` ## Conclusion Kotlin has many features I present as magic. What struck me at the beginning was to realize that everything is compilable to Java and therefore must abide with its *restrictions*. And indeed, every bit of magic here has an explanation. There are many things left unexplained in the article and you may be wondering if the language really can work as expected and if there are any drawbacks. Well, you can either read the docs yourself or trust me saying it's amazing. Good luck and happy coding! * [Kotlin Reference](https://kotlinlang.org/docs/reference/) * [The best features of Kotlin!](https://android.jlelse.eu/kotlin-best-features-a3facac4d6fd) * [Ten Kotlin Features To Boost Android Development](https://www.toptal.com/android/kotlin-boost-android-development) <!-- Safer (null safety) • Clear code (syntax, properties) + Less of code (boilerplate code) • Encourages better code design • Extension functions (many predefined functions) • Any (objects, primitive types, Unit, Nothing) • Lambdas, functional programming • Properties (accessing properties, getters/setters) • Delegated properties • Data class • Expressions with when, if • Infix operators • Destructing classes • Singleton objects • No more findViewById • Ranges • Operator overloading • Type-Safe builders • Many more -->

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully