Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Block Body

This style of function definition begins with the keyword fun, followed by

  • The function’s name
  • The parameter list, in parentheses (possibly empty)
  • A return type, if the function contains a return statement
  • The function’s body, enclosed in braces

The parameter list is a comma-separated list of parameter declarations, just as you have seen for functions in C and Python. A parameter declaration must give both the parameter’s name and its type, with a colon between the two.

The return type, if present, is preceded by a colon.

With a return Statement

Here is an example of a function with a block body and return statements:

fun anagrams(first: String, second: String): Boolean {
    if (first.length != second.length) {
        return false
    }
    val firstChars = first.lowercase().toList().sorted()
    val secondChars = second.lowercase().toList().sorted()
    return firstChars == secondChars
}

[Run this function]

This function requires two strings, represented by the parameters first and second. It compares these two strings to see whether they are anagrams of each other. Since this comparison is going to yield a true or false result, the return type is declared explicitly as Boolean. Notice that the return type comes between the parameter list and the function body, and that it is immediately preceded by a colon.

The function has two return statements. The first of these allows it to end computation early if the strings are of different lengths. Only if they are of the same length will it proceed with a more detailed comparison. This is done by converting each string to a sorted list of lowercase characters, then comparing these two lists using the == operator. The boolean result of the == expression is then returned.

Without a return Statement

If you are writing a function that doesn’t need to return a value to the caller—e.g., because it will be printing the results of computation, rather than returning those results for use elsewhere—then there is no need to specify a return type.

As an example, suppose you wish to create a function that simulates rolling any of the standard polyhedral dice used in tabletop role-playing games.

The function could be implemented like this:

fun rollDie(sides: Int) {
    if (sides in setOf(4, 6, 8, 10, 12, 20)) {
        println("Rolling a d$sides...")
        val result = Random.nextInt(1, sides + 1)
        println("You rolled $result")
    }
    else {
        println("Error: cannot have a $sides-sided die")
    }
}

[Run this function]

Notice that there is nothing between the closing parenthesis of the parameter list and the opening brace of the function body, i.e., no return type has been specified.

This example includes one thing—sets—that we haven’t discussed yet, but it should nevertheless be fairly obvious what the code is doing. The caller specifies the required die by providing the number of sides that the die has. Rolls of d4, d6, d8, d10, d12 and d20 dice are supported; any other value for number of sides results in an error message being printed.

For example, rollDie(6) simulates rolling a d6. This is achieved via a call to Kotlin library function Random.nextInt(), with arguments of 1 and 7. That call returns a pseudo-random integer in the range from 1 up to but not including 7. This integer value is then printed; it isn’t returned by the rollDie() function.

Nevertheless, rollDie() still returns something: a special value, named Unit.

All Kotlin functions return something—either an explicit value provided by the function body, or Unit. This is somewhat analogous to Python, in which functions that don’t have a return statement nevertheless still return the value None1.

Task 5.1.1

  1. Edit the file named Anagrams.kt, in the tasks/task5_1_1 subdirectory of your repository. Add to this file the code for the anagrams() function presented above.

  2. Next, add a main() function that

    • Reads in two strings from the user
    • Compares those strings using anagrams()
    • Displays the result of the comparison to the user

    Hint

    Remember that you can use the readln() function to read a string of input from the user. You should print a prompt before calling this function, so the user knows what they should be entering.

  3. Compile the program, then run it a few times to check that it is working correctly.

Task 5.1.2

  1. Edit the file named Die.kt, in the tasks/task5_1_2 subdirectory of your repository. Add to this file the code for the rollDie() function presented above.

  2. Next, add a main() function that calls rollDie() a few times, with different values for the number of die sides. Compile the program, then run it a few times to check that the function is working correctly.

    Warning

    You’ll also need to add the following import statement to the top of the file:

    import kotlin.random.Random
    
  3. Add a new function to Die.kt, named readInt(). This function should have a single String parameter, representing a prompt that will be displayed to the user. It should declare a return type of Int.

    Your implementation of this function should print the supplied prompt, read input from the user, convert the input to an Int value and then return this value.

    Hint

    You will find toInt() useful here.

    See the discussion of converting strings to numeric types for more help with this.

  4. Now modify Die.kt so that the main program allows the user to specify the number of die sides. Obviously, you should use your readInt() function to achieve this!

    Compile the program, then run it a few times to check that it is working correctly.


  1. This is not quite the same thing as void in C, C++ or Java. Use of void in those languages literally means ‘nothing is returned’. But having functions & methods always return something—even if it is just a value that isn’t useful—turns out to be a rather good idea. It makes it much easier for Kotlin to support the functional and generic programming styles.