{"id":24539052,"url":"https://github.com/farbod-s/try-kotlin","last_synced_at":"2026-05-17T12:08:15.542Z","repository":{"id":149335648,"uuid":"259018030","full_name":"farbod-s/Try-Kotlin","owner":"farbod-s","description":"Kotlin Essential Training","archived":false,"fork":false,"pushed_at":"2020-05-30T19:01:28.000Z","size":2461,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-16T03:31:38.399Z","etag":null,"topics":["android","kotlin","kotlin-android","programming","programming-language"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/farbod-s.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-04-26T11:53:02.000Z","updated_at":"2020-06-11T16:18:57.000Z","dependencies_parsed_at":"2023-11-04T02:33:34.597Z","dependency_job_id":null,"html_url":"https://github.com/farbod-s/Try-Kotlin","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/farbod-s/Try-Kotlin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/farbod-s%2FTry-Kotlin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/farbod-s%2FTry-Kotlin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/farbod-s%2FTry-Kotlin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/farbod-s%2FTry-Kotlin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/farbod-s","download_url":"https://codeload.github.com/farbod-s/Try-Kotlin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/farbod-s%2FTry-Kotlin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33137831,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-17T09:28:26.183Z","status":"ssl_error","status_checked_at":"2026-05-17T09:27:52.702Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","kotlin","kotlin-android","programming","programming-language"],"created_at":"2025-01-22T16:14:51.112Z","updated_at":"2026-05-17T12:08:15.526Z","avatar_url":"https://github.com/farbod-s.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimage src=\"./resource/logo.png\" width=\"500\"\u003e\n\nKotlin\n===\n+ kotlin is an open source language\n+ **Edu Tools** plugin from [kotlinlang.org](try.kotlinlang.org)\n\nThe Philosophy of Kotlin\n---\nA statically typed language for multiple application platforms.\n\n+ Kotlin/JVM compiles to Java bytecode\n+ Kotlin/JS transpiles to JavaScript code\n+ Kotlin/Native compiles to native binaries\n\n\u003e **Statically typed languages**: A language is statically typed if the type of a variable is known at compile time. some languages offer some form of type inference, the capability of the type system to deduce the type of a variable.\n\n\u003e **Dynamically typed languages**: A language is dynamically typed if the type is associated with run-time values, and not named variables/fields/etc.Most scripting languages have this feature as there is no compiler to do static type-checking anyway.\n\nKotlin Goals\n---\n### Concise\n+ Reduces use of unnecessary declarations and keywords\n+ Generates code that has to be explicit in Java\n+ Semi-colons not required!\n\n### Safe\n+ Avoids entire classes of errors such as null pointer exceptions\n+ Auto-casting of variables when checking types\n\n### Interoperable\n+ Kotlin/JVM code can be mixed with Java or any other JVM language\n+ Kotlin code works both in JVM and in a web browser\n\n### Tool Friendly\n+ IntelliJ IDEA includes the kotlin plugin\n+ Android Studio inherits Kotlin support\n\nHow Java Compiles to Bytecode\n---\nEach Java class in its own file compiles to a `.class` bytecode file.\n\n\u003cimage src=\"./resource/1.png\" width=\"500\"\u003e\n\nHow Kotlin Compiles to Bytecode\n---\nEach Kotlin class also compiles to a `.class` bytecode file.\n\n\u003cimage src=\"./resource/2.png\" width=\"500\"\u003e\n\nMultiple Kotlin classes\n---\nEach class in a single code file is compiled to its own bytecode file.\n\n\u003cimage src=\"./resource/3.png\" width=\"500\"\u003e\n\nCoding Conventions\n---\n### Naming Packages\n+ Package names should be in lower case with no underscores.\n+ Use camel-case if necessary for readability.\n+ Unlike Java, package and directory names don't have to match. But IntelliJ IDEA likes it when they do match!\n\n```kotlin\npackage utilities\n```\n\n### Packages in Mixed Projects\n+ Use reverse domain notation.\n\n```kotlin\npackage com.example.kotlin\n```\n\n\u003cimage src=\"./resource/4.png\" width=\"250\"\u003e\n\n### Packages in Pure Kotlin Projects\n+ Place main code file in source code root directory\n+ No package decleration needed in main code file\n+ Sub-packages have shallow names\n\n### Naming Classes and Interfaces\n+ Class and interface identifiers starts with upper-case character\n+ Use cammel-case for readablility\n\n```kotlin\ndata class Person\ninterface MyInterface {}\n```\n\n### Naming Variables\n+ Variable and function identifiers starts with lower-case character\n+ Use cammel-case for readablility\n\n```kotlin\nval number = 1\nfun add(a: Int, b: Int): Int {}\n\nval aNumber = 1\nfun addValues(a: Int, b: Int): Int {}\n```\n\n### Naming Constants\n+ Constants are declared as member of companion objects\n+ Identifiers are upper-case\n+ Use underscores fore readability\n\n```kotlin\nclass Constants {\n    companion object {\n        const val A_FIXED_VALUE = \"a fixed value\"\n    }\n}\n```\n\nKotlin Keywords\n---\n### Hard Keywords\n+ Have specific meanings everywhere\n+ Cannot be used as identifiers\n\n```kotlin\n// declare variables\nval, var\n\n// define various kinds of entities\nclass, interfcace, object\n\n// organize codes\npackage, fun, return\n\n// create code blocks\nfor, while, when, try\n\n// operators\nas, is, in, out\n\n// boolean values\ntrue, false\n```\n\n### Soft Keywords\n+ Reserved in particular contexts\n+ Can otherwise be used as identifiers\n\n```kotlin\ncatch, finally\nimport, init\nset, setparam\nconstructor, dynamic\n```\n\n### Modifier Keywords\n+ Modify effect of hard keywords\n+ Can otherwise be used as identifiers\n\n```kotlin\n// apply to classes\nenum, data, sealed, open\n\n// apply to objects\ncompanion\n\n// apply to functions\nconstructor, infix\n```\n\nBuilt-In Types\n---\n+ Unlike Java, Kotlin doesn't support primitive types\n+ Everything is a class\n+ Limited number of built-in types\n+ Numeric, characters, booleans, arrays\n\n### Numbers\n| Kotlin (Java)   | Bit width |\n| --------------- |:---------:|\n| Double (double) | 64        |\n| Float (float)   | 32        |\n| Long (long)     | 64        |\n| Int (int)       | 32        |\n| Short (short)   | 16        |\n| Byte (byte)     | 8         |\n\n### Other Built-In Types\n| Kotlin (Java)     | Notes                        |\n| ----------------- |:----------------------------:|\n| Char (char)       | Not treated as a number      |\n| Boolean (boolean) | `true` or `false`            |\n| String (String)   | always immutable             |\n| Array (n/a)       | A Kotlin class named `Array` |\n\n### Declaring a Variable\n+ Either the type or the initial value are always required\n+ Type can sometimes be inferred from initial value\n\n```kotlin\nval myVariable: Int = 1\n```\n\n\u003e **Variables**\n\u003e\n\u003e `val` means that the variable is immutable and cannot be changed once set. `var` means it is mutable.\n\n\u003cimage src=\"./resource/5.png\" width=\"250\"\u003e\n\n### Declaring a Nullable Value\n+ Initialization with `null` keyword not always required\n\n```kotlin\nval myVariable: Int? = null\n```\n\n\u003cimage src=\"./resource/6.png\" width=\"250\"\u003e\n\n### Instantiating a Class\n+ Type is inferred from constructor method call\n\n```kotlin\nval myObject = MyClass(\"parameter\")\n```\n\nString Templates\n---\n```kotlin\nprintln(\"this is my message ${message}\")\nprintln(\"this is my message $message\")\n```\n\nNumeric Values\n---\n### Type Casting\n```kotlin\nval myInt = 1\nval myLong: Long = myInt.toLong()\n\nprintln(\"the type of myLong is ${myLong::class.simpleName}\")\n// output: \"the type of myLong is kotlin.Long\"\n\nval myLong2 = 1.5\nval myInt2 = myLong2.toInt()\n\nprintln(\"the value of myInt2 is $myInt2\")\n// output: \"the value of myInt2 is 1\"\n```\n\n### Comparision\n```kotlin\nval num1 = 1\nval num2 = 2\n\n// using operator (efficient way)\nprintln(\"match is ${num1 == num2}\")\n// =\u003e System.out.println(\"match is \" + false);\n\n// using built-in methods\nprintln(\"match is ${num1.equals(num2)}\")\n// =\u003e System.out.println(\"match is \" + Integer.valueOf(num1).equals(Integer.valueOf(num2)));\n\n// using comparison method\nprintln(\"comparison result is ${num1.compareTo(num2)}\")\n// output: \"comparison result is -1\"\n// -1: less than\n//  0: is equal\n// +1: greater than\n```\n\nString Values\n---\n```kotlin\nval myString = \"hello, world\"\n\nval empty = String()\nprintln(\"'$empty'\")\n\nval charArray = myString.toCharArray()\nprintln(charArray.toList())\n\nval len = myString.length\nfor (i in 0 until len) {\n    println(\"${myString.get(i)}\")\n}\n\nval i = myString.indexOf(\"w\")\nval subString = myString.substring(i)\nprintln(subString)\n\nval myString2 = myString.toUpperCase()\nval match = myString.equals(myString2, true /*ignore case*/)\nprintln(\"match=$match\")\n\n// string concatination (efficient way)\n// in Kotlin String is immutable just like Java\n// Kotlin StringBuilder is a type alias of Java StringBuilder class\nval builder = StringBuilder(\"To be or not to be\\n\")\n        .append(\"that is the question\")\n\nval result = builder.toString()\nprintln(result)\n```\n\nConstant Values\n---\n+ Compile-time constants speed up and reduce memory usage\n\n```kotlin\nconst val myConstant = \"RED\"\nprintln(\"my constant is $myConstant\")\n// =\u003e System.out.println(\"my constant is RED\");\n```\n\n\u003e **Compile-Time Constants**\n\u003e\n\u003e Properties the value of which is known at compile time can be marked as compile time constants using the const modifier. Such properties need to fulfill the following requirements:\n\u003e * Top-level or member of an object declaration or a companion object.\n\u003e * Initialized with a value of type String or a primitive type\n\u003e * No custom getter\n\u003e\n\u003e Such properties can be used in annotations.\n\n### Declaring Constants\n```kotlin\nclass Consts {\n    companion object {\n        // using compile-time constants (efficient way)\n        const val myConstant = \"RED\"\n\n        // using Java annotations\n        @JvmField val myConstant2 = \"GREEN\"\n        // =\u003e Consts.myConstant2\n    }\n}\n```\n\nFunctions\n---\n+ Function parameters don't need `val` or `var` keywords, because they are always immutable.\n+ When passing paramters to function by name, we can change the order of parameters.\n```kotlin\nfun addValues(param1: Int, param2: Int): Int {\n    return param1 + param2\n}\n\nval result = adValues(1, 2)\n\n// passing paramters by names\nval result = addValues(param2 = 2, param1 = 1)\n```\n\n### Optional Parameters\n```kotlin\nfun calcValues(param1: Int, param2: Int, op: String = \"+\"): Int {\n    if (op.equals(\"+\")) {\n        return param1 + param2\n    } else if (op.equals(\"-\")) {\n        return param1 - param2\n    } else {\n        return -1\n    }\n}\n\nval result = calcValues(1, 2)\nval result2 = calcValues(1, 2, \"-\")\n```\n\n### Variable Arguments\n```kotlin\nfun addValues(vararg numbers: Int): Int {\n    var result = 0\n    for (num in numbers) {\n        result += num\n    }\n    return result\n}\n\nval result = addValues(1, 2, 3, 4, 5)\n```\n\n\u003e **On the JVM**: the named argument syntax cannot be used when calling Java functions because Java bytecode does not always preserve names of function parameters.\n\n### Unit-Returning Functions\nIf a function does not return any useful value, its return type is `Unit`. `Unit` is a type with only one value `Unit`. This value does not have to be returned explicitly:\n\n```kotlin\nfun printHello(name: String?): Unit { // the `Unit` return type declaration is also optional\n    if (name != null)\n        println(\"Hello ${name}\")\n    else\n        println(\"Hi there!\")\n    // `return Unit` or `return` is optional\n}\n```\n\n### Single-Expression Functions\nWhen a function returns a single expression, the curly braces can be omitted and the body is specified after a `=` symbol:\n\n```kotlin\nfun double(x: Int): Int = x * 2\n```\n\nExplicitly declaring the return type is optional when this can be inferred by the compiler.\n\n### Generic Functions\nFunctions can have generic parameters which are specified using angle brackets before the function name:\n```kotlin\nfun \u003cT\u003e singletonList(item: T): List\u003cT\u003e { /*...*/ }\n```\n\n### Tail Recursive Functions\nKotlin supports a style of functional programming known as tail recursion. This allows some algorithms that would normally be written using loops to instead be written using a recursive function, but without the risk of stack overflow. When a function is marked with the `tailrec` modifier and meets the required form, the compiler optimises out the recursion, leaving behind a fast and efficient loop based version instead:\n\n```kotlin\nval eps = 1E-10 // \"good enough\", could be 10^-15\n\ntailrec fun findFixPoint(x: Double = 1.0): Double\n        = if (Math.abs(x - Math.cos(x)) \u003c eps) x else findFixPoint(Math.cos(x))\n```\n\nThe resulting code is equivalent to this more traditional style:\n\n```kotlin\nprivate fun findFixPoint(): Double {\n    var x = 1.0\n    while (true) {\n        val y = Math.cos(x)\n        if (Math.abs(x - y) \u003c eps) return x\n        x = Math.cos(x)\n    }\n}\n```\n\nTo be eligible for the `tailrec` modifier, a function must call itself as the last operation it performs. You cannot use tail recursion when there is more code after the recursive call, and you cannot use it within try/catch/finally blocks.\nCurrently, tail recursion is supported by Kotlin for JVM and Kotlin/Native.\n\n### [Is Java **pass-by-reference** or **pass-by-value**?](http://www.javadude.com/articles/passbyvalue.htm)\nThe Java Spec says that everything in Java is **pass-by-value**. There is no such thing as **~~pass-by-reference~~** in Java.\n\n\u003e Objects are not passed by reference. A correct statement would be **Object References** are passed by value.\n\n```java\npublic void foo(Dog d) {\n    d = new Dog(\"Fifi\"); // creating the \"Fifi\" dog\n}\n\nDog aDog = new Dog(\"Max\"); // creating the \"Max\" dog\n// at this point, `aDog` points to the \"Max\" dog\n\nfoo(aDog); \n// `aDog` still points to the \"Max\" dog\n```\n\nthe variable passed in, `aDog`, is not modified! After calling `foo()`, `aDog` still points to the `Dog` with name `\"Max\"`!\n\nMany people mistakenly think/state that something like:\n```java\npublic void foo(Dog d) { \n    d.setName(\"Fifi\");\n}\n```\n\n\u003e When you declare and instantiate an object. The actual object goes on the heap. What goes on the stack? The address of the object on the heap. C++ programmers would call this a pointer, but some Java developers are against the word \"pointer\". Whatever. Just know that the address of the object goes on the stack.\n\n### [Is Kotlin **pass-by-value** or **pass-by-reference**?](https://stackoverflow.com/a/54689951/2034849)\nIt uses the same principles like Java. It is always pass-by-value, you can imagine that a copy is passed. For primitive types, e.g. `Int` this is obvious, the value of such an argument will be passed into a function and the outer variable will not be modified. Please note that parameters in Kotlin cannot be reassigned since they act like `val`s.\n\n```kotlin\nfun takeInt(a: Int) {\n    // this code will not compile because `a` cannot be reassigned.\n    a = 5\n}\n```\n\nFor objects it's a bit more difficult but it's also call-by-value. If you call a function with an object, a copy of its reference is passed into that function:\n\n```kotlin\ndata class SomeObj(var x: Int = 0)\n\nfun takeObject(o: SomeObj) {\n    o.x = 1\n}\n\nfun main(args: Array\u003cString\u003e) {\n    val obj = SomeObj()\n    takeObject(obj)\n    println(\"obj after call: $obj\") // SomeObj(x=1)\n}\n```\n\nYou can use a reference passed into a function to change the actual object. This will influence the argument you passed in. But the reference itself, i.e. the value of the variable, will never be changed via a function call.\n\n### Top-Level Functions\nTop-level functions are functions inside a Kotlin package that are defined outside of any class, object, or interface. This means that they are functions you call directly, without the need to create any object or call any class.\n\n\u003e Given that Java doesn't support top-level functions, the Kotlin compiler behind the scenes will create a Java class, and the individual top-level functions will be converted to static methods.\n\nNote that we can change the Java class name that the Kotlin compiler generates by using the `@JvmName` annotation.\n\n```kotlin\n@file:JvmName(\"UserUtils\")\npackage com.chikekotlin.projectx.utils\n \nfun checkUserStatus(): String {\n    return \"online\"\n}\n```\n\n### Lambda Expressions\nHere are the characteristics of a lambda expression in Kotlin:\n+ It must be surrounded by curly braces `{}`.\n+ It doesn't have the `fun` keyword. \n= There is no access modifier (`private`, `public` or `protected`) because it doesn't belong to any class, object, or interface.\n+ It has no function name. In other words, it's anonymous. \n+ No return type is specified because it will be inferred by the compiler.\n+ Parameters are not surrounded by parentheses `()`.\n\nAnd, what's more, we can assign a lambda expression to a variable and then execute it.\n\n```kotlin\nval addNumbers = { number1: Int, number2: Int -\u003e\n    val result = number1 + number2\n    println(\"The result is $result\")\n}\naddNumbers(1, 3)\n```\n\nWe can pass lambda expressions as parameters to functions: these are called **higher-order functions**, because they are functions of functions. These kinds of functions can accept a lambda or an anonymous function as parameter.\n\n```kotlin\nval stringList: List\u003cString\u003e = listOf(\"in\", \"the\", \"club\")\nstringList.f({ s: String -\u003e s.length == 3})\n\n// the Kotlin compiler allows us to remove the function parentheses if the last argument in the function is a lambda expression.\nstringList.last { s: String -\u003e s.length == 3 }\n\n// we can make it more concise by removing the parameter type\n// we don't need to specify the parameter type explicitly, because the parameter type is always the same as the collection element type.\nstringList.last { s -\u003e s.length == 3 }\n```\n\nWe can even simplify the lambda expression further again by replacing the lambda expression argument with the auto-generated default argument name `it`.\n\n```kotlin\nstringList.last { it.length == 3 }\n```\n\nThe `it` argument name was auto-generated because `last` can accept a lambda expression or an anonymous function (we'll get to that shortly) with only one argument, and its type can be inferred by the compiler.\n\n\u003e The last expression in a lambda is considered the return value.\n\nWe can explicitly return a value from the lambda using the qualified return syntax. Otherwise, the value of the last expression is implicitly returned.\n\n```kotlin\nints.filter {\n    val shouldFilter = it \u003e 0 \n    shouldFilter\n}\n\nints.filter {\n    val shouldFilter = it \u003e 0 \n    return@filter shouldFilter\n}\n```\n\nIf the lambda parameter is unused, you can place an underscore instead of its name:\n\n```kotlin\nmap.forEach { _, value -\u003e println(\"$value!\") }\n```\n\n#### Local Return in Lambda Expressions\n```kotlin\nfun surroundingFunction() {\n    val intList = listOf(1, 2, 3, 4, 5)\n    intList.forEach {\n        if (it % 2 == 0) {\n            return@forEach\n        }\n    }\n    println(\"End of surroundingFunction()\") // Now, it will execute\n}\n \nsurroundingFunction() // print \"End of surroundingFunction()\"\n```\n\nThe return statement won't return from the lambda but instead from the containing function `surroundingFunction()`.\n\nTo fix this problem, we need to tell it explicitly which function to return from by using a label or name tag.\n\nIn the updated code above, we specified the default tag `@forEach` immediately after the `return` keyword inside the lambda. We have now instructed the compiler to return from the lambda instead of the containing function `surroundingFunction()`. Now the last statement of `surroundingFunction()` will execute.\n\nNote that we can also define our own label or name tag:\n```kotlin\n// ...\nintList.forEach myLabel@ {\n    if (it % 2 == 0) {\n        return@myLabel\n// ...\n```\n\nIn the code above, we defined our custom label called `myLabel@` and then specified it for the `return` keyword. The `@forEach` label generated by the compiler for the `forEach` function is no longer available because we have defined our own.\n\n#### Closures\nA lambda expression or anonymous function (as well as a local function and an object expression) can access its closure, i.e. the variables declared in the outer scope. The variables captured in the closure can be modified in the lambda:\n\n```kotlin\nvar sum = 0\nints.filter { it \u003e 0 }.forEach {\n    sum += it\n}\nprint(sum)\n```\n\n### Higher-Order Functions\nA higher-order function is a function that takes functions as parameters, or returns a function.\n\n```kotlin\nfun \u003cT, R\u003e Collection\u003cT\u003e.fold(\n    initial: R, \n    combine: (acc: R, nextElement: T) -\u003e R\n): R {\n    var accumulator: R = initial\n    for (element: T in this) {\n        accumulator = combine(accumulator, element)\n    }\n    return accumulator\n}\n```\n\nIn the code above, the parameter combine has a function type `(R, T) -\u003e R`, so it accepts a function that takes two arguments of types `R` and `T` and returns a value of type `R`.\n\n### Function Types\n- All function types have a parenthesized parameter types list and a return type: `(A, B) -\u003e C` denotes a type that represents functions taking two arguments of types `A` and `B` and returning a value of type `C`. The parameter types list may be empty, as in `() -\u003e A`. The `Unit` return type cannot be omitted.\n- Function types can optionally have an additional receiver type, which is specified before a dot in the notation: the type `A.(B) -\u003e C` represents functions that can be called on a receiver object of `A` with a parameter of `B` and return a value of `C`. Function literals with receiver are often used along with these types.\n- Suspending functions belong to function types of a special kind, which have a `suspend` modifier in the notation, such as `suspend () -\u003e Unit` or `suspend A.(B) -\u003e C`.\n\nThe function type notation can optionally include names for the function parameters: `(x: Int, y: Int) -\u003e Point`. These names can be used for documenting the meaning of the parameters.\n\nTo specify that a function type is nullable, use parentheses: `((Int, Int) -\u003e Int)?`.\n\nFunction types can be combined using parentheses: `(Int) -\u003e ((Int) -\u003e Unit)`\n\nThe arrow notation is right-associative, `(Int) -\u003e (Int) -\u003e Unit` is equivalent to the previous example, but not to `((Int) -\u003e (Int)) -\u003e Unit`.\n\nYou can also give a function type an alternative name by using a type alias:\n```kotlin\ntypealias ClickHandler = (Button, ClickEvent) -\u003e Unit\n```\n\n#### Instantiating a Function Type\n- Using a code block within a function literal, in one of the forms:\n    - a lambda expression: `{ a, b -\u003e a + b }`\n    - an anonymous function: `fun(s: String): Int { return s.toIntOrNull() ?: 0 }`\n- Using a callable reference to an existing declaration:\n    - a top-level, local, member, or extension function: `::isOdd, String::toInt`\n    - a top-level, member, or extension property: `List\u003cInt\u003e::size`\n    - a constructor: `::Regex`\n- Using instances of a custom class that implements a function type as an interface:\n\n```kotlin\nclass IntTransformer: (Int) -\u003e Int {\n    override operator fun invoke(x: Int): Int = TODO()\n}\n\nval intFunction: (Int) -\u003e Int = IntTransformer()\n```\n\n#### Invoking a Function Type Instance\nA value of a function type can be invoked by using its **invoke(...)** operator: `f.invoke(x)` or just `f(x)`.\n\n```kotlin\nval stringPlus: (String, String) -\u003e String = String::plus\nval intPlus: Int.(Int) -\u003e Int = Int::plus\n\nprintln(stringPlus(\"Hello, \", \"world!\"))  // Hello, world!\n\nprintln(intPlus.invoke(1, 1)) // 2\nprintln(intPlus(1, 2)) // 3\n\n// extension-like call\nprintln(2.intPlus(3)) // 5\n```\n\n### Inline Functions\nUsing higher-order functions imposes certain runtime penalties: each function is an object, and it captures a closure, i.e. those variables that are accessed in the body of the function. Memory allocations (both for function objects and classes) and virtual calls introduce runtime overhead.\n\nBut it appears that in many cases this kind of overhead can be eliminated by inlining the lambda expressions.\n\n```kotlin\ninline fun \u003cT\u003e lock(lock: Lock, body: () -\u003e T): T { ... }\n```\n\nInlining may cause the generated code to grow; however, if we do it in a reasonable way (i.e. avoiding inlining large functions), it will pay off in performance, especially at \"megamorphic\" call-sites inside loops.\n\n#### Noinline\nIn case you want only some of the lambdas passed to an inline function to be inlined, you can mark some of your function parameters with the `noinline` modifier:\n\n```kotlin\ninline fun foo(inlined: () -\u003e Unit, noinline notInlined: () -\u003e Unit) { ... }\n```\n\n### Member Functions\nThis kind of function is defined inside a class, object, or interface. Using member functions helps us to modularize our programs further.\n\n### Anonymous Functions\nAn anonymous function is another way to define a block of code that can be passed to a function. It is not bound to any identifier. Here are the characteristics of an anonymous function in Kotlin:\n+ has no name\n+ is created with the fun keyword\n+ contains a function body\n\n```kotlin\nval strLenThree = stringList.last( fun(string): Boolean {\n    return string.length == 3\n})\nprint(strLenThree) // will print \"the\"\n```\n\nIn the above code, we have replaced the lambda expression with an anonymous function because we want to be explicit about the return type. \n\nThe return expression returns from the anonymous function and not from the surrounding one:\n```kotlin\nfun surroundingFunction() {\n    val intList = listOf(1, 2, 3, 4, 5)\n    intList.forEach ( fun(number) {\n        if (number % 2 == 0) {\n            return\n        }\n    })\n    println(\"End of surroundingFunction()\") // statement executed\n}\n \nsurroundingFunction() // will print \"End of surroundingFunction()\"\n```\n\n\u003e Lambda expressions and anonymous functions are **function literals**, i.e. functions that are not declared, but passed immediately as an expression. Consider the following example:\n```kotlin\nmax(strings, { a, b -\u003e a.length \u003c b.length })\n```\nFunction `max` is a higher-order function, it takes a function value as the second argument. This second argument is an expression that is itself a function, i.e. a function literal, which is equivalent to the following named function:\n```kotlin\nfun compare(a: String, b: String): Boolean = a.length \u003c b.length\n```\n\n### Local or Nested Functions\nA local function is a function that is declared inside another function.\n\nThe nested functions can be called only from within the enclosing function and not outside.\n\nWe can make our local functions more concise by not explicitly passing parameters to them. This is possible because local functions have access to all parameters and variables of the enclosing function.\n\n```kotlin\nfun printCircumferenceAndArea(radius: Double): Unit {\n    fun calCircumference(): Double = (2 * Math.PI) * radius\n    val circumference = \"%.2f\".format(calCircumference())\n \n    fun calArea(): Double = (Math.PI) * Math.pow(radius, 2.0)\n    val area = \"%.2f\".format(calArea())\n    // ...\n}\n```\n\n### [Infix Functions](https://code.tutsplus.com/tutorials/kotlin-from-scratch-more-functions--cms-29479)\nThe `infix` notation allows us to easily call a one-argument member function or extension function. In addition to a function being one-argument, you must also define the function using the `infix` modifier. To create an infix function, two parameters are involved. The first parameter is the target object, while the second parameter is just a single parameter passed to the function.\n\n\u003e Infix function calls have lower precedence than the arithmetic operators, type casts, and the rangeTo operator.\n\u003e \n\u003e - 1 shl 2 + 3 is equivalent to 1 shl (2 + 3)\n\u003e - 0 until n * 2 is equivalent to 0 until (n * 2)\n\u003e - xs union ys as Set\u003c*\u003e is equivalent to xs union (ys as Set\u003c*\u003e)\n\n\u003e On the other hand, infix function call's precedence is higher than that of the boolean operators \u0026\u0026 and ||, is- and in-checks, and some other operators.\n\u003e\n\u003e - a \u0026\u0026 b xor c is equivalent to a \u0026\u0026 (b xor c)\n\u003e - a xor b in c is equivalent to (a xor b) in c\n\n#### Creating an Infix Member Function\n```kotlin\nclass Student {\n    var kotlinScore = 0.0\n     \n    infix fun addKotlinScore(score: Double): Unit {\n        this.kotlinScore = kotlinScore + score\n    }\n}\n```\n\n#### Calling an Infix Function\n+ we don't need to use the dot notation\n+ we don't need to wrap the parameter with parentheses\n```kotlin\nval student = Student()\nstudent addKotlinScore 95.00\nprint(student.kotlinScore) // will print \"95.0\"\n```\n\n#### The `to` Infix Function\nIn Kotlin, we can make the creation of a `Pair` instance more succinct by using the `to` infix function instead of the `Pair` constructor. (Behind the scenes, `to` also creates a `Pair` instance.)\n\nNote that the `to` function is also an extension function:\n```kotlin\npublic infix fun \u003cA, B\u003e A.to(that: B): Pair\u003cA, B\u003e = Pair(this, that)\n```\n\ncompare the creation of a map by using both the `to` infix function and the `Pair` constructor to create the individual pairs:\n\n```kotlin\nval nigeriaCallingCodePair = 234 to \"Nigeria\"\nval nigeriaCallingCodePair2 = Pair(234, \"Nigeria\") // same as above\nval nigeriaCallingCodePair3 = 234.to(\"Nigeria\") // same as using 234 to \"Nigeria\"\n\nval callingCodesMap: Map\u003cInt, String\u003e = mapOf(234 to \"Nigeria\", 1 to \"USA\", 233 to \"Ghana\")\nval callingCodesPairMap: Map\u003cInt, String\u003e = mapOf(Pair(234, \"Nigeria\"), Pair(1, \"USA\"), Pair(233, \"Ghana\"))\n```\n\n### Extension Function\nKotlin provides the ability to extend a class with new functionality without having to inherit from the class or use design patterns such as Decorator. For example, you can write new functions for a class from a third-party library that you can't modify.\n\nTo declare an extension function, we need to prefix its name with a receiver type, i.e. the type being extended.\n\n```kotlin\nfun MutableList\u003cInt\u003e.swap(index1: Int, index2: Int) {\n    // the this keyword inside an extension function corresponds to the receiver object (the one that is passed before the dot).\n    val tmp = this[index1] // 'this' corresponds to the list\n    this[index1] = this[index2]\n    this[index2] = tmp\n}\n```\n\nExtension cannot be overloaded. So, it’s impossible to use the override keyword to modify the behavior of an extension that’s already been created.\n\nIf a class has a member function, and an extension function is defined which has the same receiver type, the same name, and is applicable to given arguments, the member always wins.\n\n\u003e **Extensions are resolved statically**\n\u003e\n\u003e Extensions do not actually modify classes they extend. By defining an extension, you do not insert new members into a class, but merely make new functions callable with the dot-notation on variables of this type.\n\u003e\n\u003e Extension functions are dispatched statically, i.e. they are not virtual by receiver type. This means that the extension function being called is determined by the type of the expression on which the function is invoked, not by the type of the result of evaluating that expression at runtime.\n\n### Extension Properties\n```kotlin\nval \u003cT\u003e List\u003cT\u003e.lastIndex: Int\n    get() = size - 1\n```\n\nNote that, since extensions do not actually insert members into classes, there's no efficient way for an extension property to have a backing field. This is why **initializers are not allowed for extension properties**. Their behavior can only be defined by explicitly providing getters/setters.\n\n```kotlin\nval House.number = 1 // error: initializers are not allowed for extension properties\n```\n\n### Declaring Extensions as Members\nInside a class, you can declare extensions for another class. Inside such an extension, there are multiple implicit receivers - objects members of which can be accessed without a qualifier. The instance of the class in which the extension is declared is called **dispatch receiver**, and the instance of the receiver type of the extension method is called **extension receiver**.\n\n```kotlin\nclass Host(val hostname: String) {\n    fun printHostname() { print(hostname) }\n}\n\nclass Connection(val host: Host, val port: Int) {\n    fun printPort() { print(port) }\n\n    fun Host.printConnectionString() {\n        printHostname() // calls Host.printHostname()\n        print(\":\")\n        printPort() // calls Connection.printPort()\n    }\n\n    fun connect() {\n        /*...*/\n        host.printConnectionString() // calls the extension function\n    }\n}\n\nfun main() {\n    Connection(Host(\"kotl.in\"), 443).connect()\n    //Host(\"kotl.in\").printConnectionString(443)  // error, the extension function is unavailable outside Connection\n}\n```\n\nIn case of a name conflict between the members of the dispatch receiver and the extension receiver, the extension receiver takes precedence. To refer to the member of the dispatch receiver you can use the qualified `this` syntax.\n\n```kotlin\nclass Connection {\n    fun Host.getConnectionString() {\n        toString() // calls Host.toString()\n        this@Connection.toString() // calls Connection.toString()\n    }\n}\n```\n\nExtensions declared as members can be declared as `open` and overridden in subclasses. This means that the dispatch of such functions is virtual with regard to the dispatch receiver type, but static with regard to the extension receiver type.\n\n```kotlin\nopen class Base { }\n\nclass Derived : Base() { }\n\nopen class BaseCaller {\n    open fun Base.printFunctionInfo() {\n        println(\"Base extension function in BaseCaller\")\n    }\n\n    open fun Derived.printFunctionInfo() {\n        println(\"Derived extension function in BaseCaller\")\n    }\n\n    fun call(b: Base) {\n        b.printFunctionInfo() // call the extension function\n    }\n}\n\nclass DerivedCaller: BaseCaller() {\n    override fun Base.printFunctionInfo() {\n        println(\"Base extension function in DerivedCaller\")\n    }\n\n    override fun Derived.printFunctionInfo() {\n        println(\"Derived extension function in DerivedCaller\")\n    }\n}\n\nfun main() {\n    BaseCaller().call(Base()) // \"Base extension function in BaseCaller\"\n    DerivedCaller().call(Base()) // \"Base extension function in DerivedCaller\" - dispatch receiver is resolved virtually\n    DerivedCaller().call(Derived()) // \"Base extension function in DerivedCaller\" - extension receiver is resolved statically\n}\n```\n\n### Extension Visibility\n- An extension declared on top level of a file has access to the other private top-level declarations in the same file.\n- If an extension is declared outside its receiver type, such an extension cannot access the receiver's private members.\n\nConditions\n---\n```kotlin\nval state = readline()\nval capital: String?\n\nwhen (state) {\n    \"CA\" -\u003e capital = \"Sacramento\"\n    \"OR\" -\u003e capital = \"Salem\"\n    \"NH\", \"VT\", \"MA\" -\u003e capital = \"New England\"\n    else -\u003e capital = \"Unknown\"\n}\n\nprintln(\"The capital is $capital\")\n```\nor\n```kotlin\nval state = readline()\nval capital = when (state) {\n    \"CA\" -\u003e \"Sacramento\"\n    \"OR\" -\u003e \"Salem\"\n    \"NH\", \"VT\", \"MA\" -\u003e \"New England\"\n    else -\u003e \"Unknown\"\n}\n\nprintln(\"The capital is $capital\")\n```\n\n```kotlin\nval answer = 42\nwhen (answer) {\n    in 1..49 -\u003e println(\"Not yet\")\n    in 50..75 -\u003e println(\"Close enough\")\n    else -\u003e {\n        println(\"Definitely not!\")\n        println(\"No really\")\n    }\n}\n```\nor\n```kotlin\nwhen {\n    number \u003c 1 -\u003e print(\"Number is less than 1\")\n    number \u003e 1 -\u003e print(\"Number is greater than 1\")\n}\n```\n\n### Null Values\n```kotlin\nvar nullvalue: String? = null\nprintln(\"nullValue is $nullValue\") // null\n\nval length: Int? = nullValue?.length\nprintln(\"length is $length\") // length is null\n\nval message = if (length != null) \"length is $length\" else \"length is null\"\nprintln(message)\n\nval length2: Int = length ?: -1\nprintln(\"length2 is $length2\") // length2 is -1\n\nval length3: Int = length!!\ntry {\n    print(\"length3 is $length3\") // will raise KotlinNullPointerException because length is null\n} catch(e: KotlinNullPointerException) {\n    println(\"length3 is null\")\n}\n```\n\n### Loops\n```kotlin\nval colors = arrayOf(\"Red\", \"Green\", \"Blue\")\nval values = intArrayOf(1, 3, 5, 7, 9)\n\n// for each loop\nfor (color in colors) {\n    println(color)\n}\n\n// for loop with indices\nfor (i in values.indices step 2) {\n    println(values[i])\n}\n\nfor (i in 0 until colors.size) { // 0..colors.size - 1\n    println(colors[i])\n}\n\n// while loop\nvar counter = 0\nwhile (counter \u003c colors.size) {\n    println(\"color = ${colors[counter]}\")\n    ++counter\n}\n\n// do/while loop\ncounter = 0\ndo {\n    println(\"color = ${colors.get(counter)}\")\n    ++counter\n} while (counter \u003c colors.size)\n```\n\nClasses\n---\n### Object\nKotlin has language support for creating singletons with the `object` keyword.\n\n### Companion Object\nThe same as with normal objects, companion objects cannot have constructors, but can extend other classes and implement interfaces.\n```kotlin\nclass MathLib {\n    companion object {\n        fun addValues(num1: Int, num2: Int) = num1 + num2\n    }\n}\n```\n\n### Enum Class\n```kotlin\nenum class Operation(val operator: String) {\n    ADD(\"+\"), SUBTRACT(\"-\"), MULTIPLY(\"*\"), DIVIDE(\"/\")\n}\n```\n\n### Data Class\nTo ensure consistency and meaningful behavior of the generated code, data classes have to fulfill the following requirements:\n\n- The primary constructor needs to have at least one parameter;\n- All primary constructor parameters need to be marked as `val` or `var`;\n- Data classes cannot be abstract, open, sealed or inner;\n- (before 1.1) Data classes may only implement interfaces.\n\n```kotlin\n// primary constructor\ndata class ClothingItem(val type: String,\n                        val size: String,\n                        val price: Double)\n\nfun main() {\n    val item = ClothingItem(\"Short\", \"L\", 19.99)\n    println(item) // ClothingItem(type=short, size=L, price=19.99)\n}\n```\n\n### Class Constructors\n```kotlin\n// primary constructor\ndata class ClothingItem constructor (var type: String?,\n                        val size: String,\n                        val price: Double) {\n    // executed when primary constructor called\n    init {\n        type = type?.toUpperCase() ?: \"UNKNOWN\"\n    }\n\n    // secondary constructor: has to daisy chain to primary constructor\n    constructor(size: String, price: Double): this(null, size, price) {\n        // type = \"Unknown\"\n    }\n}\n\nfun main() {\n    val item = ClothingItem(\"M\", 14.99)\n    println(item) // ClothingItem(type=UNKNOWN, size=M, price=14.99)\n}\n```\n\n### Class Properties\n```kotlin\ndata class ClothingItem(private var _type: String?,\n                        val size: String,\n                        private var _price: Double) {\n    var type: String? = _type\n        get() = field ?: \"Unknown\"\n\n    var price = _price\n        set(value) {\n            field = value * .9\n        }\n}\n\nfun main() {\n    val item = ClothingItem(\"M\", 14.99)\n    println(\"item type = ${item.type}\") // item type = Unknown\n\n    item.price = 10.0\n    println(\"item price = ${item.price}\") // item price = 9.0\n}\n```\n\n### Inheritance\n```kotlin\nopen class SuperClass(anInt: Int) {\n    protected val _anInt = anInt\n\n    override fun toString(): String {\n        return \"${this::class.simpleName} [anInt: $_anInt]\"\n    }\n\n    open fun multiply(factor: Int): Int {\n        return _anInt * factor\n    }\n}\n\nclass SubClass(anInt: Int): SuperClass(anInt) {\n    override fun multiple(factor: Int): Int {\n        return super.multiply(factor) * factor\n    }\n}\n```\n \n### Interface\n```kotlin\ninterface Dog {\n    var fur: String\n    fun speak() {\n        println(\"Woof!\")\n    }\n}\n\ninterface Cat {\n    var fur: String\n    fun speak() {\n        println(\"Meow!\")\n    }\n}\n\nclass Retriever: Dog, Cat  {\n    override var fur: String\n        get() = \"golder\"\n        set(value) {}\n\n    override fun speak() {\n        super\u003cDog\u003e.speak()\n    }\n}\n\nfun makeItTalk(dog: Dog) {\n    dog.speak()\n}\n\nfun reportBreed(name: String, dog: Dog) {\n    println(\"$name is a ${dog::class.simpleName}\")\n}\n\nfun main() {\n    val buster = Retriever()\n    makeItTalk(buster)\n    reportBreed(\"Buster\", buster)\n}\n```\n\n### Callbacks\n```kotlin\nclass ClickEvent(x: Int, y: Int)\n\ninterface ClickListener {\n    fun onClick(event: ClickEvents)\n}\n\nclass StatefulWidget(listener: ClickListener) {\n    private var _listener: ClickListener? = listener\n\n    fun click(x: Int, y: Iny) {\n        listener?.onClick(ClickEvent(x, y))\n    }\n}\n\nfun main() {\n    // using anonymous object\n    val widget = StatefulWidget(object: ClickListener {\n        override fun onClick(event: ClickEvent) {\n            println(\"clicked at (${event.x}, ${event.y})s\")\n        }\n    })\n\n    widget.click(5, 18)\n}\n```\n\n### Sealed Class\n```kotlin\n// abstract class\nsealed class ClothingItem(val type: String) {\n    abstract val size: String\n    abstract val price: Double\n}\n\n// subclasses must be in the same code file\ndata class Shirt(override var size: String,\n                 override var price: Double): ClothingItem(\"Shirt\")\n\ndata class Pants(override var size: String,\n                 override var price: Double): ClothingItem(\"Pants\")\n\nfun main() {\n    val item1 = Shirt(\"XL\", 19.99)\n    val item2 = Pants(\"32\", 24.99)\n\n    val mostExpensive =\n            if (item1.price \u003e item2.price) item1 else item2\n\n    val instructions = when(mostExpensive) {\n        is Shirt -\u003e \"Button it!\"\n        is Pants -\u003e \"Buckle it!\"\n    }\n\n    println(instructions)\n}\n```\n\nMore Kotlin\n---\n\n### Enums\nEnums are **exhaustive** in `when` expressions (`switch` in Java). In Kotlin, we can return on expressions or assign a value to one, forcing each branch of the expression to supply a valid value to fulfill the expression return type.\n\n\u003e In **Java**, `enum` are static singleton objects that cannot have multiple instances.\n\n### Sealed Class\n**Sealed Classes** are a special kind of class such that the Kotlin compiler can verify all subtypes during compilation, adding some unique benefits.\n\nTo allow our `enum` to hold state, but have the compiler verify we covered all cases of an instance, we change the declaration to a `sealed class`.\n\n```kotlin\nsealed class Result \u003cout T: Any\u003e {\n    data class Success \u003cout T: Any\u003e (val data: T): Result\u003cT\u003e()\n    data class Error(val exception: Exception): Result\u003cNothing\u003e()\n    object InProgress: Result\u003cNothing\u003e()\n}\n\nfun handleResult(result: Result\u003cInt\u003e) {\n    val action = when(result) {\n        is Result.Success -\u003e {}\n        is Result.Error -\u003e {}\n        Result.InProgress -\u003e {}\n    }.exhaustive\n}\n\nval \u003cT\u003e.exhaustive: T\n    get() = this\n```\n\n### Unit\n`Unit` in Kotlin corresponds to the `void` in Java. Like void, Unit is the return type of any function that does not return any meaningful value, and it is optional to mention the Unit as the return type. But unlike void, Unit is a real class (Singleton) with only one instance.\n\n### Nothing\n`Nothing` is a type in Kotlin that represents \"a value that never exists\", that means just \"no value at all\".\n\n### `lateinit` vs `lazy`\n`lateinit`:\n- Use it with mutable variable `var`\n```kotlin\nlateinit var name: String       //Allowed\nlateinit val name: String       //Not Allowed\n```\n\n- Allowed with only **non-nullable** data types\n```kotlin\nlateinit var name: String       //Allowed\nlateinit var name: String?      //Not Allowed\n```\n\n- It is a promise to compiler that the value will be initialized in future.\n\n\u003e If you try to access `lateinit` variable without initializing it then it throws `UnInitializedPropertyAccessException`.\n\n`lazy`:\n- Lazy initialization was designed to prevent unnecessary initialization of objects.\n- Your variable will not be initialized unless you use it.\n- It is initialized only once. Next time when you use it, you get the value from cache memory.\n- It is thread safe (It is initializes in the thread where it is used for the first time. Other threads use the same value stored in the cache).\n- The variable can only be `val`.\n- The variable can only be **non-nullable**.\n\n```kotlin\nval aVar by lazy {\n    println(\"I am computing this value\") // prints only once\n    \"Hola\" // the return value of lambda expression\n}\n\nfun main(args: Array\u003cString\u003e) {\n    println(aVar)\n    println(aVar)\n}\n\n// Result:\n// \"I am computing this value\"\n// \"Hola\"\n// \"Hola\"\n```\n\n### Type Checks and Casts\n#### `is` and `!is` Operators\nWe can check whether an object conforms to a given type at runtime by using the `is` operator or its negated form `!is`:\n```kotlin\nif (obj is String) {\n    print(obj.length)\n}\n\nif (obj !is String) { // same as !(obj is String)\n    print(\"Not a String\")\n}\n```\n\n#### Smart Casts\nIn many cases, one does not need to use explicit cast operators in Kotlin, because the compiler tracks the `is`-checks and explicit casts for immutable values and inserts (safe) casts automatically when needed.\n\nThe compiler is smart enough to know a cast to be safe if a negative check leads to a return.\n\nor in the right-hand side of `\u0026\u0026` and `||`.\n\n```kotlin\nfun demo(x: Any) {\n    if (x is String) {\n        print(x.length) // x is automatically cast to String\n    }\n}\n\nif (x !is String) return\nprint(x.length) // x is automatically cast to String\n\n// x is automatically cast to string on the right-hand side of `||`\nif (x !is String || x.length == 0) return\n\n// x is automatically cast to string on the right-hand side of `\u0026\u0026`\nif (x is String \u0026\u0026 x.length \u003e 0) {\n    print(x.length) // x is automatically cast to String\n}\n\nwhen (x) {\n    is Int -\u003e print(x + 1)\n    is String -\u003e print(x.length + 1)\n    is IntArray -\u003e print(x.sum())\n}\n```\n\n#### \"Unsafe\" cast operator\nUsually, the cast operator throws an exception if the cast is not possible. Thus, we call it unsafe. The unsafe cast in Kotlin is done by the infix operator `as`:\n```kotlin\nval x: String = y as String\n```\n\nNote that null cannot be cast to `String` as this type is not nullable, i.e. if `y` is null, the code above throws an exception. To make such code correct for null values, use the nullable type on the right hand side of the cast:\n```kotlin\nval x: String? = y as String?\n```\n\n#### \"Safe\" (nullable) cast operator\nTo avoid an exception being thrown, one can use a safe cast operator `as?` that returns `null` on failure:\n```kotlin\nval x: String? = y as? String\n```\nNote that despite the fact that the right-hand side of `as?` is a non-null type `String` the result of the cast is nullable.\n\n### Coroutines\nKotlin Coroutines are like lightweight threads. They are lightweight because creating coroutines doesn’t allocate new threads. Instead, they use predefined thread pools, and smart scheduling. Scheduling is the process of determining which piece of work you will execute next.\n\nAdditionally, coroutines can be **suspended** and **resumed** mid-execution. This means you can have a long-running task, which you can execute little-by-little. You can pause it any number of times, and resume it when you’re ready again.\n\n#### CoroutineScope\n- Keep track of coroutines\n- Ability to cancel ongoing work\n- Notified when a failure happens \n\n```kotlin\nval scope = CoroutineScope(Job())\nval job = scope.launch {\n    // Coroutine\n}\n```\n\n\u003e Cancelling the scope **cancels its children**.\n\u003e\n\u003e a **cancelled** child doesn't affect other siblings.\n\n#### Job\n- Provides lifecycle\n- Couroutine hierarchy\n\n#### Job Lifecycle\n**States**:\n- New, Active\n- Completing, Completed\n- Cancelling, Cancelled\n\n**Properties**:\n- isActive\n- isCancelled\n- isCompleted\n\n\u003cimage src=\"./resource/7.png\" width=\"500\"\u003e\n\n#### CoroutineContext\nDefines the behavior of coroutine and consist set of elements with default values:\n- CoroutineDispatcher -\u003e Threading (Dispatchers.Default)\n- Job -\u003e Lifecycle (No parent Job)\n- CoroutineExceptionHandler (None)\n- CoroutineName (\"coroutine\")\n\n\u003e a **new coroutine** inherits the parent context.\n\u003e\n\u003e Parent context = Defaults + inherited context + arguments\n\u003e \n\u003e Coroutine context = parent context + Job()\n\n#### Cooperative Cancellation\n`val isActive`:\n- Do an action before finishing the coroutine.\n\n`fun ensureActive()`:\n- Instantaneously stop work.\n\n`suspend fun yield()`:\n- CPU heavy computation that may exhaust thread-pool.\n- Checks if the coroutine Job was completed. If yes, throws `CancellationException`.\n\n\u003e **PRO TIP**: All the suspending functions in `Kotlin.coroutines` are **cancellable**.\n\u003e\n\u003e If you create your own suspend functions, make them cancellable.\n\n### Singleton\n```kotlin\nobject SomeSingleton\n```\nThe above Kotlin object will be compiled to the following equivalent Java code:\n```kotlin\npublic final class SomeSingleton {\n   public static final SomeSingleton INSTANCE;\n\n   private SomeSingleton() {\n      INSTANCE = (SomeSingleton)this;\n      System.out.println(\"init complete\");\n   }\n\n   static {\n      new SomeSingleton();\n   }\n}\n```\n\nThis is the preferred way to implement singletons on a JVM because it enables thread-safe lazy initialization without having to rely on a locking algorithm like the complex double-checked locking.\n\n### `suspending` vs. `blocking`\n- A **blocking** call to a function means that a call to any other function, from the same thread, will halt the parent’s execution. Following up, this means that if you make a blocking call on the main thread’s execution, you effectively freeze the UI. Until that blocking calls finishes, the user will see a static screen, which is not a good thing.\n\n- **Suspending** doesn’t necessarily block your parent function’s execution. If you call a suspending function in some thread, you can easily push that function to a different thread. In case it is a heavy operation, it won’t block the main thread. If the suspending function has to suspend, it will simply pause its execution. This way you free up its thread for other work. Once it’s done suspending, it will get the next free thread from the pool, to finish its work.\n\n\u003e Suspending functions can invoke any other regular functions, but to actually suspend the execution, it has to be another suspending function. A suspending function cannot be invoked from a regular function, therefore several so-called coroutine builders are provided, which allow calling a suspending function from a regular non-suspending scope like `launch`, `async`, `runBlocking`.\n\n### Flow\nUsing the `List\u003cInt\u003e` result type, means we can only return all the values at once. To represent the stream of values that are being asynchronously computed, we can use a `Flow\u003cInt\u003e` type just like we would the `Sequence\u003cInt\u003e` type for synchronously computed values:\n\n```kotlin\nsuspend fun foo(): List\u003cInt\u003e {\n    delay(1000) // pretend we are doing something asynchronous here\n    return listOf(1, 2, 3)\n}\n\nfun main() = runBlocking\u003cUnit\u003e {\n    foo().forEach { value -\u003e println(value) } \n}\n```\n\n```kotlin\nfun foo(): Flow\u003cInt\u003e = flow { // flow builder\n    for (i in 1..3) {\n        delay(100) // pretend we are doing something useful here\n        emit(i) // emit next value\n    }\n}\n\nfun main() = runBlocking\u003cUnit\u003e {\n    // Launch a concurrent coroutine to check if the main thread is blocked\n    launch {\n        for (k in 1..3) {\n            println(\"I'm not blocked $k\")\n            delay(100)\n        }\n    }\n    // Collect the flow\n    foo().collect { value -\u003e println(value) } \n}\n\n// Result:\n// I'm not blocked 1\n// 1\n// I'm not blocked 2\n// 2\n// I'm not blocked 3\n// 3\n```\n\n- A builder function for `Flow` type is called `flow`.\n- Code inside the `flow { ... }` builder block can suspend.\n- The function `foo()` is no longer marked with `suspend` modifier.\n- Values are emitted from the flow using `emit` function.\n- Values are collected from the flow using `collect` function.\n\n\u003e We can replace `delay` with `Thread.sleep` in the body of foo's `flow { ... }` and see that the main thread is blocked in this case.\n\nFlows are cold streams similar to sequences — the code inside a flow builder does not run until the flow is collected.\n\n\u003e **Hot Observables**: are ones that are pushing event when you are not subscribed to the observable. Like mouse moves, or Timer ticks or anything like that.\n\u003e\n\u003e **Cold Observables**: are ones that start pushing only when you subscribe, and they start over if you subscribe again.\n\n### Scope Functions\nfunctions whose sole purpose is to execute a block of code within the context of an object without its name.\nThere are five of them: `let`, `run`, `with`, `apply`, and `also`.\n\nThere are two main differences between each scope function:\n- The way to refer to the context object\n- The return value.\n\nEach scope function uses one of two ways to access the context object: as a lambda receiver (`this`) or as a lambda argument (`it`).\n\n`run`, `with`, and `apply` refer to the context object as a lambda receiver - by keyword `this`.\n\n```kotlin\nval adam = Person(\"Adam\").apply { \n    age = 20 // same as this.age = 20 or adam.age = 20\n    city = \"London\"\n}\nprintln(adam)\n```\n\n`let` and `also` have the context object as a lambda argument. If the argument name is not specified, the object is accessed by the implicit default name `it`.\n\n```kotlin\nfun getRandomInt(): Int {\n    return Random.nextInt(100).also {\n        writeToLog(\"getRandomInt() generated value $it\")\n    }\n}\n\nval i = getRandomInt()\n```\n\nThe scope functions differ by the result they return:\n- `apply` and `also` return the context object.\n- `let`, `run`, and `with` return the lambda result.\n\n```kotlin\nval numberList = mutableListOf\u003cDouble\u003e()\nnumberList.also { println(\"Populating the list\") }\n    .apply {\n        add(2.71)\n        add(3.14)\n        add(1.0)\n    }\n    .also { println(\"Sorting the list\") }\n    .sort()\n```\n\n```kotlin\nval numbers = mutableListOf(\"one\", \"two\", \"three\")\nval countEndsWithE = numbers.run { \n    add(\"four\")\n    add(\"five\")\n    count { it.endsWith(\"e\") }\n}\nprintln(\"There are $countEndsWithE elements that end with e.\")\n```\n\n| Function | Object reference | Return value | Is extension function |\n| --- | --- | --- | --- |\n| let | it | Lambda result | Yes |\n| run | this | Lambda result | Yes |\n| run | - | Lambda result | No: called without the context object |\n| with | this | Lambda result | No: takes the context object as an argument. |\n| apply | this | Context object | Yes |\n| also | it | Context object | Yes |\n\nHere is a short guide for choosing scope functions depending on the intended purpose:\n\n- Executing a lambda on non-null objects: `let`\n- Introducing an expression as a variable in local scope: `let`\n- Object configuration: `apply`\n- Object configuration and computing the result: `run`\n- Running statements where an expression is required: non-extension `run`\n- Additional effects: `also`\n- Grouping function calls on an object: `with`\n\nOverriding vs Overloading\n---\nOverloading happens at compile-time while Overriding happens at runtime: The binding of overloaded method call to its definition happens at compile-time however binding of overridden method call to its definition happens at runtime.\n\n\u003e **Static binding** in Java occurs during compile time.\n\u003e\n\u003e **Dynamic binding** occurs during runtime.\n\nStatic methods can be overloaded which means a class can have more than one static method of same name. Static methods cannot be overridden, even if you declare a same static method in child class it has nothing to do with the same method of parent class as overridden static methods are chosen by the reference class and not by the class of the object.\n\n```java\npublic class Animal {\n    public static void testClassMethod() {\n        System.out.println(\"The static method in Animal\");\n    }\n\n    public void testInstanceMethod() {\n        System.out.println(\"The instance method in Animal\");\n    }\n}\n\npublic class Cat extends Animal {\n    public static void testClassMethod() {\n        System.out.println(\"The static method in Cat\");\n    }\n\n    public void testInstanceMethod() {\n        System.out.println(\"The instance method in Cat\");\n    }\n\n    public static void main(String[] args) {\n        Cat myCat = new Cat();\n        myCat.testClassMethod();\n        Animal myAnimal = myCat;\n        myAnimal.testClassMethod();\n        myAnimal.testInstanceMethod();\n    }\n}\n\n/*\nResult:\n// testClassMethod() is called from \"Cat\" reference\n\"The static method in Cat\"\n\n// testClassMethod() is called from \"Animal\" reference,\n// ignoring actual object inside it (Cat)\n\"The static method in Animal\"\n\n// testInstanceMethod() is called from \"Animal\" reference,\n// but from \"Cat\" object underneath\n\"The instance method in Cat\"\n*/\n```\n\nDictionary\n---\n\n### What are Domain Specific Languages (DSLs)\nA Domain Specific Language is a programming language with a higher level of abstraction optimized for a specific class of problems. A DSL uses the concepts and rules from the field or domain.\n\n### Parameter vs Argument\n**Parameter** is variable defined in function declaration. \n\n**Argument** is the actual value of this variable that get passed to the function.\n\n**Type parameter** is blueprint or placeholder for a type declared in generic.\n\n**Type argument** is actual type used to parametrize generic.\n\n### Statement vs Expression\n**Expression** in a programming language is a combination of one or more explicit values, constants, variables, operators and functions that the programming language interprets and computes to produce another value.\nAn expression is every part of code that returns value.\n\n**Statement** is the smallest standalone element of an imperative programming language that expresses some action to be carried out.\n\n#### What is an expression in Java vs in Kotlin?\nNote, that there are some fundamental differences between what is, and what is not an **expression** in Kotlin and in Java. All Kotlin functions calls are **expressions**, because they return at least `Unit`. Calls of Java functions that do not defined any return type are not **expressions**. Kotlin value assignment (`a = 1`) is **not an expression** in Kotlin, while it is in Java because over there it returns assigned value (in Java you can do `a = b = 2` or `a = 2 * (b = 3)`). All usages of control structures (`if, switch`) in Java are not expressions, while Kotlin allowed `if`, `when` and `try` to return values:\n\n```kotlin\nval bigger = if(a \u003e b) a else b\nval color = when {\n    relax -\u003e GREEN\n    studyTime -\u003e YELLOW\n    else -\u003e BLUE\n}\nval object = try {\n    gson.fromJson(json)\n} catch (e: Throwable) {\n    null\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffarbod-s%2Ftry-kotlin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffarbod-s%2Ftry-kotlin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffarbod-s%2Ftry-kotlin/lists"}