Functions

The fun keyword define new function.

Kotlin functions can be declared at the top level in a file, meaning you do not need to create a class to hold a functionlike in Java.

Kotlin functions can also be declared locally, as member functions (nested functions) and extension functions.

/* general syntax
fun <func-name>(<arg-name>:<arg-type>): <return-type>{

}
*/

fun sum(a: Int, b: Int) : Int {
    return a+b
}

passing arguments

A method can have a list of arguments in parentheses, separated by commas.

Argument may have default value.

You can skip all arguments with default values.

You can skip some arguments with default values. However, after the first skipped argument, you must name all subsequent arguments.

fun reformat(
    str: String,
    normalizeCase: Boolean = true,
    upperCaseFirstLetter: Boolean = true,
    divideByCamelHumps: Boolean = false,
    wordSeparator: Char = ' ',
) { /*...*/ }

// use all arguments with default values
reformat("This is a long String!")

// normalizeCase and wordSeparator arguments with default values
reformat("This is a short String!", 
    upperCaseFirstLetter = false, 
    wordSeparator = '_')

variable-length argument

The vararg modifier specifies the variable number of arguments.

Only one parameter can be marked as vararg. If a vararg parameter is not the last one in the list, values for the following parameters can be passed using the named argument syntax, or, if the parameter has a function type, by passing a lambda outside parentheses.

If you already have an array and want to pass its contents to the function, use the spread operator *.

fun <T> asList(vararg ts: T): List<T> {
    val result = ArrayList<T>()
    for (t in ts) // ts is an Array
        result.add(t)
    return result
}

val list1 = asList(1, 2, 3)

val a = arrayOf(1, 2, 3)
val list2 = asList(-1, 0, *a, 4)

return value

The return statement finishes function execution and return specified value if necessary to caller.

The Unit type is default return type of function.

Declaration of return type can be omitted for type Unit or when a function returns a single expression.

fun printHello(name: String?): Unit {
    if (name != null)
        println("Hello $name")
    else
        println("Hi there!")
    // `return Unit` or `return` is optional
}

// return type omitted
fun printHello(name: String?) { ... }

// function with single expression
fun double(x: Int): Int = x * 2

// return type omitted
fun double(x: Int) = x * 2

overloading

Kotlin supports overloading. This means, you can have several functions with same name but with different number of arguments or types of arguments in the same scope.

recursion

The tailrec modifier says to the compiler to optimize the recursion to the efficient loop.

val eps = 1E-10 // "good enough", could be 10^-15

tailrec fun findFixPoint(x: Double = 1.0): Double =
    if (Math.abs(x - Math.cos(x)) < eps) x else findFixPoint(Math.cos(x))

// will be transformed to the

val eps = 1E-10 // "good enough", could be 10^-15

private fun findFixPoint(): Double {
    var x = 1.0
    while (true) {
        val y = Math.cos(x)
        if (Math.abs(x - y) < eps) return x
        x = Math.cos(x)
    }
}