Kotlin promises concise, expressive and safe code. In the previous articles I covered topics like basic types, control flow instructions, equality checks, null safety.
In this article we will have some fun with functions and learn new keywords from the Kotlin Wonderland.
Functions are the basic building block of any program. In Kotlin functions are declared with the fun keyword and they are first-class citizen. It means that functions can be assigned to the variables, passed as an arguments or returned from another function.
π Function vs. Method
Function and method are two commonly confused words. While every method is a function, not every function is a method.
A function returns a value, and a method is a function associated to an object. Function is a more general term, and all methods are also functions.
πGeneral syntax of a function in Kotlin
// Kotlin syntax for main function
// It returns nothing useful (Unit) and takes no arguments.
fun main() {
println("Hello Kotlin!")
}
// equivalent Kotlin syntax
fun add(a: Int, b: Int): Int {
return a + b
}
fun add(a: Int, b: Int): Int = a + b
fun add(a: Int, b: Int) = a + b
π Default Arguments Functions
Kotlin supports default arguments in function declarations. A default value can be specified for a function parameter and it is used when the corresponding argument is omitted from the function call.
// default parameter values
fun displayTitleAndName(name: String, prefix: String = "dr") {
println("$prefix $name")
}
π Named Arguments Functions
We are able to specify the names of arguments that we are passing to the function. This makes the function calls more readable. It also allows us to pass the value of a parameter selectively if other parameters have default values.
// named arguments
fun getFullName(firstName: String, lastName: String): String {
return "$firstName $lastName"
}
getFullName(lastName = "Miu", firstName = "Magda")
π Infix Functions
Member functions and extensions with a single parameter can be turned into infix functions.
class Utility {
// infix functions = functions with a single parameter
infix fun String.onto(other: String) = Pair(this, other)
}
fun main(args: Array<String>) {
val blueShoes = "blue".onto("shoes")
val yellowScarf = "yellow" onto "scarf"
println(blueShoes) // => (blue, shoes)
println(yellowScarf) // => (yellow, scarf)
}
π Functions with Varargs parameters
Varargs allow you to pass any number of arguments by separating them with commas.
// functions with varargs parameters
fun varargExample(vararg names: Int) {
println("Argument has ${names.size} elements")
}
varargExample() // => Argument has 0 elements
varargExample(1) // => Argument has 1 elements
varargExample(1, 2, 3) // => Argument has 3 elements
π Tail Recursive Functions
- Tail recursion is a generic concept rather than the feature of Kotlin language. Kotlin use it to optimize recursive calls.
- In normal recursion, you perform all recursive calls first, and calculate the result from return values at last.
- In tail recursion, calculations are performed first, then recursive calls are executed.
- A recursive function is eligible for tail recursion if the function call to itself is the last operation it performs.
// factorial
tailrec fun factorial(n: Int, run: Int = 1): Long {
return if (n == 1) run.toLong() else factorial(n - 1, run \* n)
}
π Extension Functions
- An extension function is a member function of a class that is defined outside the class.
- Extensions are resolved statically and can also be defined with the class type that is nullable.
- If a class contains a companion object, then we can also define extension functions and properties for the companion object.
fun String.removeFirstLastChar(): String = this.substring(1, this.length - 1)
println("Kotlin".removeFirstLastChar()) // => otli
π High Order Functions
A function that can accept a function as a parameter or can return a function.
// high order function = fun with fun or fun returns a fun
fun add(a: Int, b: Int): Int {
return a + b
}
fun returnAddFunction(): ((Int, Int) -> Int) {
return ::add
}
π Operator Overloading
In Java, operators are connected to specific Java types. For example, we can use + operator in order to concatenate Strings, but no other Java type can reuse this operator for its own benefit. But Kotlin provides a set of conventions to support limited Operator Overloading.
Certain functions can be βupgradedβ to operators, allowing their calls with the corresponding operator symbol.
// operator functions = functions "upgraded" to operators
data class IntListWrapper(val wrapped: List<Int>) {
operator fun get(position: Int): Int = wrapped[position]
}
val listOfNumbers = IntListWrapper(listOf(1, 2, 3))
println(listOfNumbers[1]) // => 2
π Lambda
- A lambda expression or an anonymous function is a βfunction literalβ, i.e. a function that is not declared, but passed immediately as an expression
- A lambda expression is always surrounded by curly braces
- Its parameters (if any) are declared before -> (parameter types may be omitted)
- The body goes after -> (when present)
// returning from a lambda
val calculateGrade = { grade : Int ->
when(grade) {
in 0..40 -> "Fail"
!is Int -> "Just a grade"
in 41..70 -> "Pass"
in 71..100 -> "Distinction"
else -> false
}
}
println(calculateGrade(57)) // => Pass
Enjoy and feel free to leave a comment if something is not clear or if you have questions. And if you like it please π and share !
Thank you for reading! πππβ
Follow me on Twitter Magda Miu
Top comments (0)