Sunday 4 March 2018

Functions in Kotlin


Function: Functions are the basic building block of any program. In this article, youll learn how to declare and call functions in Kotlin.

Functions in Kotlin are declared using the fun keyword.

Following is the general syntax of declaring a function in Kotlin.
             fun functionName(param1: Type1, param2: Type2,..., paramN: TypeN): Type {
             // Method Body
                }

Every function declaration has a function name, a list of comma-separated parameters, an optional return type, and a method body. The function parameters must be explicitly typed.
 Example:-

                 Function Declaration

               fun add(x:Int,y:Int):Int{
               return x+y
                   }

     Calling Function

              add(3,5)

Here the return Type of Function is integer.

Single Expression Functions:You can omit the return type and the curly braces if the function returns a single expression. The return type is inferred by the compiler from the expression -

                         fun mul(a: Int, b: Int) = a * b

                            mul(5, 3)  // 15

Unit returning FunctionsFunctions which dont return anything has a return type of Unit. The Unit type similar to void in Java.
                     
 Example:-
                               fun printSub(a: Int, b: Int): Unit {
                         println("Subtraction of $a, $b = ${a - b}")
                          }

                         printSub(10, 3)  // Subtraction of 103 = 7
Note that, the Unit type declaration is completely optional. So you can also write the above function declaration like this -
                        fun printSub(a: Int, b: Int) {
                       println("Subtraction of $a, $b = ${a - b}")
                  }


Variable Number of Arguments (Varargs):You can pass a variable number of arguments to a function by declaring the function with a vararg parameter.

                         
 Example:-

                           fun sumOfNumbers(vararg numbers: Int): Int {
                                    var sum: Int= 0
                                    for(no in numbers) {
                                          sum =sum+ no
                                        }
                               return sum
                       }

You can call the above function with any number of arguments -

                            sumOfNumbers(1, 2)  // Result = 3

                           sumOfNumbers(1,2,3,4,5)  // Result = 15


 

Spread Operator

Usually, we pass the arguments to a vararg function one-by-one. But if you already have an array and want to pass the elements of the array to the vararg function, then you can use the spread operator like this -
                
                    val list = asList(1, 2, 3)

                    sumOfNumbers(*a)  // Result = 6


Tail Recursion function: Tail recursion is a generic concept rather than the feature of Kotlin language. Some programming languages including Kotlin use it to optimize recursive calls, whereas other languages (eg. Python) do not support them.


What is tail recursion?

In normal recursion, you perform all recursive calls first, and calculate the result from return values at last. Hence, you don't get result until all recursive calls are made.
In tail recursion, calculations are performed first, then recursive calls are executed (the recursive call passes the result of your current step to the next recursive call). This makes the recursive call equivalent to looping, and avoids the risk of stack overflow.


Condition for tail recursion

A recursive function is eligible for tail recursion if the function call to itself is the last operation it performs.You cannot use tail recursive when there is more code after the recursive call,

 For example,
Example 1: Not eligible for tail recursion because the function call to itself n*factorial(n-1) is not the last operation.
                             fun factorial(n: Int): Long {

                                            if (n == 1) {
                                                   return n.toLong()
                                            } else {
                                           return n*factorial(n - 1)     
                                               }
                                }

Example 2: Eligible for tail recursion because function call to itself fibonacci(n-1, a+b, a) is the last operation.No other operation with Function call
                              fun fibonacci(n: Int, a: Long, b: Long): Long {
                                    return if (n == 0) b else fibonacci(n-1, a+b, a)
                                   }

To tell compiler to perform tail recursion in Kotlin, you need to mark the function with tailrec modifier.

Example: Factorial Using Tail Recursion

The example to compute factorial of a number in the above example (first example) cannot be optimized for tail recursion. Here's a different program to perform the same task.
                 fun main(args: Array<String>) {
                                   val number = 6
                                  println("Factorial of $number = ${factorial(number)}")}

                                tailrec fun factorial(n: Int, run: Int = 1): Long {
                                 return if (n == 1) run.toLong() else factorial(n-1, run*n)}




When you run the program, the output will be:
Factorial of 6 = 720
The compiler can optimize the recursion in this program as the recursive function is eligible for tail recursion, and we have used tailrec modifier that tells compiler to optimize the recursion.

No comments:

Post a Comment