Kotlin Methods / Functions

What is a function?

A method, as well called function or subroutine, is a sequence of program instructions that performs a specific task. A function encapsulates a certain functionality. The function can be called from different locations and thus reduces code duplications.

In Kotlin, to declare a function the keyword fun is used. In general, a function has 4 parts:

  • function name
  • input argument list
  • output argument
  • function body

In the following example the function has the name addNumber. The function needs 2 integers as argument list. In the function body the actual work is defined. In this case it adds the numbers. The return value is defined in the declaration (: Int). At the end of the function a value / object must be returned which fits the declared return type.

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

In Kotlin functions can be stand alone or part of a class. If a function is part of a class, it is called member function. In this tutorial the focus is on standalone functions.

Function name

The name of the function may be the most important part of a function. It tells the programmer what the function is doing. A wrong name gives confusion and will lead eventually to errors. It is important to give a function a name of what the function actually does. Function name should use verbs (e.g. add, convert, …). Function which start with the name has is / can shall return a Boolean (e.g. canConvert(), hasAccess(), isConvertable()). Most guidelines prefer to use mixedCase for the function name (addNumberconvertSomething, …).

A function name must start with a character. Numbers are not allowed as first character (1hasNumber()). Most special characters are not allowed. It is advised to use only alphabetic letters.

One should be careful to not create hidden secondary effects in the function. The function should do, what the name says. In object-oriented design, member functions which return something, shall not alter the state of the object.

Parameters

The arguments passed into a function are treated as value types. This means they are constant and cannot be modified. Since they are constant it is not from importance to think about if they are passed by value or by reference. Therefore, it is not possible to have out-parameters. If you need to have multiple return values, you should use an appropriate class structure, which holds the data.

But what happens, if you want to modify the value of the input parameter. For example, you want to add a substring to a string. In this case you must create a string and assign it to the original one. On the first sight this is a huge overhead. It implies several constructor calls to create the strings. On the other hand, this follows the rule of functional programming. With the increasing speed and ram in today’s computer, the overhead becomes in general small.

fun addString(inputString: String) : String
{
    return inputString + "Append"
}

var mString = "SomeText"
mString = addString(mString)

Function as a parameter

Since functions are in Kotlin first class citizens theey can be handled as any other object. It is therefor possible in Kotlin to use functions as input parameter. The following code snipped is showing this behaviour:

fun myFunction(exec : ()-> Unit) {
    exec()
}

fun main(){
    var mFunctor : ()->Unit = {println("Hello World")}
    myFunction(mFunctor)
}

Default Arguments

Input arguments can have default values, which are used when the corresponding argument is not specified. Every parameter can have a default value and it is not important at which position the parameter is. In the following example the second parameter has a default value while the first and third parameter are not optional.

fun addNumbers(a: Int, b: Int = 5, c: Int)
{
    val sum = a + b + c
    println(sum)
}

addNumbers(a = 5, c = 10)

Variable number of arguments (Varargs)

A parameter of a function may be marked with the vararg modifier. This allows multiple number of arguments. The arguments will be passed as array.

fun <TType> asList(vararg ts: TType): List<TType> {
    val result = ArrayList<TType>()
    for (t in ts)
        result.add(t)
    return result
}

Return argument

The return value can be either a Unit (void) or be an explicit type. If a function returns nothing the return type is a Unit. This is special in the programming language Kotlin but is nothing to worry about. It is preferred to skip the return value declaration if nothing is returned. In the following example both functions are doing the same. The first function is preferred because it does not declare the Unit return value.

fun printSomething(){
    println("printSomething")
}

fun printSomethingElse() : Unit
{
    println("printSomethingElse")
}

A function can return maximal one variable. If you need to return multiple variables, they need to be structured together in class structures. It is not possible to have out-(input) values like in C++ or C#. Neither is it possible to return multiple variables like in Python.

Function body

Scope of variables

The variables which are created in the function only exist until the end of the function. At the end of the function, all variables will be deleted.

Single expression function

If a function returns a single expression, the curly braces can be omitted, and the body is specified after the = symbol.

fun addNumber(a: Int, b: Int) : Int = a + b

Function in functions

Kotlin provides the functionality to define function within the scope of functions. The local function is only accessible within the outer function. The inner function has access to all variables in the scope of the outer function. A variable will be shadowed in case of same names of inner and outer variables. In the following example the inner function shadows the variable a, because this variable is as well defined as input parameter of the outer function.

fun outerFunction(a: Int, b: Int)
{
   fun innerFunction(a: Int)
   {
       println("InnerFunction: ")
       println(a)
       println(b)
   }

    println("OuterFunction:")
    innerFunction(a)
    innerFunction(b)
}

Generic functions

Generic function will have generic input or output parameter. This function can then be called with different types. At compile time it is checked if invoked types are compatible with the function implementation.

fun <TType> addNumber(a: TType, b: TType) : TType = a + b