Erica Knows Nothing About Kotlin: Kotlin functions

Yesterday, I got my feet wet creating a simple functional chain to calculate the sum of natural numbers that are multiples of 3 or 5 (thanks Jeff):

var result = (1 .. limit - 1)
    .filter { item -> item.divisibleBy(3) || item.divisibleBy(5) }

As you can see, Kotlin looks a lot like Swift. And, like any programming language, you can collect a routine into a function (fun rather than func in Kotlin, which makes Kotlin seem like a very “happy fun™” language) for re-use.

Instead of using a temporary result variable (var, just like in Swift, although let is val) and re-assigning it at each calculation, it’s more elegant to create a reusable component to call for each limit.

The simplest way is to build a function that mimics Swift. You declare fun, the function name, parameters, the return type (with a : token), and use the return keyword to establish the return value:

fun Int.divisibleBy(factor: Int) = this % factor == 0

fun euler1 (limit: Int) : Int {
    return (1 .. limit - 1)
        .filter { item -> item.divisibleBy(3) ||item.divisibleBy(5) }
println("The sum of these multiples is ${euler1(10)}")
println("The sum of these multiples is ${euler1(1000)}")

I also munged the calls directly into the print string using ${}. This is basically the same as using \() in Swift. The new  euler1 function is now almost indistinguishable from Swift.

Kotlin offers a bit more flexibility in its function declarations. You can skip the braces and use assignment to the compound expression, creating an inferred scope for short expressions:

fun euler1 (limit: Int) : Int = (1 .. limit - 1)
        .filter { item -> item.divisibleBy(3) ||item.divisibleBy(5) }

Same results, much streamlined declaration.

Like Swift, you can introduce defaulted arguments into your parameter list. This example can be called with zero or one arguments, allowing the printed phrase to default to “Hello World”.

fun greet(phrase: String = "Hello World") = println(phrase)
greet() // "Hello World"
greet("Hello Sailor") // "Hello Sailor"

You can also create functional closures/lambda expressions and assign them to variables, as you do in Swift. And, as in Swift, that closure can then be treated like a normal function:

var add : (Int, Int) -> Int = {item, increase -> item + increase }
println(add) // Function2<java.lang.Integer, java.lang.Integer, java.lang.Integer>
println(add(2, 3)) // 5

Finally, like Swift, you can create infix functionality, such as exponentiation. The first two examples use the infix form, the second two use a standard function call:

infix fun Int.exp(exponent: Int): Int {
    return (1 .. exponent)
        .asSequence().map { this }
        .fold(1) {current, base -> current * base }

println(5 exp 3) // 125
println(2 exp 8) // 256
println(5.exp(3)) // 125
println(2.exp(8)) // 256

One Comment

  • Presumably you mean “multiples of 3 *or* 5”.
    Sorry to be pedantic but when you’re showing code examples, it’s good if the prose matches.