The documentation for Kotlin is now located on the new site. This page is kept for historical reasons
Skip to end of metadata
Go to start of metadata
The documentation for Kotlin is now located on the new site. This page is kept for historical reasons

If expression

In Kotlin, if is an expression, i.e. it returns a value. Therefore there is not ternary operator (condition ? then : else), because ordinary if works fine in this role. Consider the following examples:

// Traditional usage 
var max = a 
if (a < b) 
  max = b 
 
// With else 
var max : Int 
if (a > b) 
  max = a 
else 
  max = b 
 
// As expression 
val max = if (a > b) a else b

If branches can be blocks, and the last expression is the value of a block:

val max = if (a > b) { 
    print("Choose a") 
    a 
  } 
  else { 
    print("Choose b") 
    b 
  }

When if has only one branch, or one of its branches results in Unit, it's type is Unit.

See the grammar for if here.

When expression

When replaces the switch operator of C-like languages. In the simplest form it looks like this:

when (x) { 
  1 -> print("x == 1") 
  2 -> print("x == 2") 
  else -> { // Note the block 
    print("x is neither 1 nor 2") 
  } 
}

When matches its argument against all branches consequently until some branch condition is satisfied. When is an expression and results in satisfied branch's right hand side. If some of its branches return result in a value of type Unit, the whole expression has type Unit.
Note that the else branch is mandatory, unless the compiler can prove that all possible cases are covered with branch conditions.

If many cases should be handled in the same way, the branch conditions may be combined with a comma:

when (x) { 
  0, 1 -> print("x == 0 or x == 1") 
  else -> print("otherwise") 
}

We can use arbitrary expressions (not only constants) as branch conditions:

when (x) { 
  parseInt(s) -> print("s encodes x") 
  else -> print("s does not encode x") 
}

One can also check a value for being in or !in a range:

when (x) { 
  in 1..10 -> print("x is in the range") 
  !in 10..20 -> print("x is outside the range") 
  else -> print("none of the above") 
}


When can also be used as a replacement for an if-else-if chain. If no argument is supplied, the branch conditions are simply boolean expressions, and a branch is executed when its condition is true:

when { 
  x.isOdd() -> print("x is odd") 
  x.isEven() -> print("x is even") 
  else -> print("x is funny") 
}

Continue inside when

Inside when expressions, continue jumps to the next branch condition, if any:

when (x) { 
  in 1..100 -> 
    if (x.isOdd()) 
      continue // Jump to the next branch, i.e. '3, 101 -> ...' 
    else 
      print("Even between 1 and 100") 
  3, 101 -> print("3 or 101") 
  1000 -> 
continue
 // Error: continue is not allowed in the last branch 
}

This mechanism replaces the concept of guards available in other languages. I.e. in Scala one has guard if expressions in match (that corresponds to when):

This can be rewritten in Kotlin with as follows:

when(term) { 
  is Fun -> { if (tem.v != term.body) continue; print(x) } 
  else -> print("Nope!") 
}

See Returns and jumps for more information about continue.

See the grammar for when here.

Continue in when is not implemented yet
See the corresponding issue


For loop

For loop iterates through anything that provides an iterator. The syntax is as follows:

for (item in collection) 
  print(item)

The body can be a block.

for (item : Int in ints) { 
  // ... 
}

As mentioned before, for iterates through anything that provides and iterator, i.e.

  1. has an instance- or extension-function iterator(), whose return type
  2. has an instance- or extension-function next(), and
  3. has an instance- or extension-function hasNext() that returns Boolean.

If you want to iterate through an array or list with an index, you can do it this way:

for (i in array.indices) 
  print(array[i])

Note that this "iteration through a range" is compiled down to optimal implementation with no extra objects created.

See the grammar for for here.

While and do..while loops

While and do..while work as usual:

while(x > 0) { 
  x-- 
} 
 
do { 
  val y = retrieveData() 
} while(y != null) // y is visible here!

See the grammar for while here.

Break and continue in loops

Kotlin supports traditional break and continue operators in loops. See more here Returns and jumps.

Try expression

See Exceptions for the details.

What's next

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Jul 20, 2011

    Anonymous

    Please can we have the same syntax for arrays. An array is a collection. The compiler can figure it out. 

    Secondly, this would be huge, can we have multiple collections, iterated in parallel:

    The above should throw an exception if the sizes dont match, or fail to compile if the collections dont have a size. This would compile tho:

    1. Jul 20, 2011

      Array is not the special case in Kotlin, so it'll with arrays. Parallel iteration can be expresses, for instance, with extension function to a tuple of collections. The code will look like this

      1. May 21, 2012

        Could you provide a working example?

        1. May 23, 2012

          The library code for this is not there yet, sorry. The main idea is this:

          class Pair<A, B>(val a : A, val b : B) 
           
          fun <A, B> Pair<out Iterable<A>, out Iterable<B>>.forEach(f : (A, B) -> Unit) { 
            val ia = a.iterator() 
            val ib = b.iterator() 
            while (ia.hasNext() && ib.hasNext()) { 
              val va = ia.next() 
              val vb = ib.next() 
              f(va, vb) 
            } 
          } 
           
          fun test() { 
            val a = list(1, 2, 3) 
            val b = list("1", "2", "3") 
            Pair(a, b).forEach { a, b -> 
              println("a = $a, b = $b") 
            } 
          }
  2. Jul 21, 2011

    Anonymous

    Since you permit "in" in "when" statements, perhaps there is also a case for other binary comparison operators? e.g.

    or can this be somehow expressed with ranges already (open upper/lower boundaries)?

    1. Jul 21, 2011

      As can be seen in your example, the code becomes rather ugly this way with all those "< 1 =>" and stuff... And you can't have + there, for it has a prefix form... So, we are not sure what's good here

      1. Jul 21, 2011

        Anonymous

        Yes, I tried writing this down with "<=", and it looks downright ugly. Having open-ended ranges solve this much neater - something like "(1..)" and "(..100)"; or perhaps "(1..)" and "(..100)", since you tend to use "*"  for wildcards:

        1. Jul 21, 2011

          If you need comparisons in particular, we have this (may be dropped later):

          when (x) { 
              .lessThan(0) => ... 
              in 1..10 => ... 
              .greaterThan(10) => ... 
            } 
           
            inline fun Int.lessThan(y : Int) = this < y 
            inline fun Int.greaterThan(y : Int) = this > y
  3. Jul 21, 2011

    Anonymous

    I'm not entirely sure from the examples provided, but it looks like "continue" is a jump statement rather than an expression. Does this mean that it cannot be used in expression contexts at all? e.g. can I write:

    It would be nice if the above was valid. Of course, this begs the question of what the type of "continue" then is, since it now has to be an expression. It would require introducing a bottom type to the type system. But then you could also give the same treatment to "break" and "return", so that crazy things like "1 + break @foo" become possible. :)

    On the other hand, an even niftier feature would be to have something like expression "continue", but with the ability to further modify the value in our branch. Something like <xsl:next-match/> from XSTL, basically:

    1. Jul 21, 2011

      continue is a legitimate expression of type Nothing. Your first example is perfectly OK in Kotlin.

  4. Jul 25, 2011

    Anonymous

    I applaud your decision of making Kotlin control structures expressions, but have you considered dropping the parentheses around the predicate rather than keeping them mandatory as in the C/C++/Java heritage? For one thing, for expressions would flow more naturally, as in

    And by making the curly braces mandatory instead of the parentheses, you would on one move remove the infamous dangling else problem and a common source of errors when extending a one-line control structure without curly braces. I think that alone would help your language a little further on the way towards industrial use.

    Of course, syntax familiarity might be a more important criterion...

    1. Jul 27, 2011

      One problem with this is the if expression that replaces the ternary operator:

      val x = if (y > 0) 1 else 2

      With curly braces that would be strange

  5. Feb 03, 2012

    Please add a way to getting the index in for loops without having to create one explicitly. For example:

    Or for maps:

    In current java, it's very annoying to always write code like this:

    1. Feb 03, 2012

      Currently you can say:

      for (i in array.indices) { 
        ... 
      }
      1. Feb 03, 2012

        I know. But if I use a for loop to iterate over a collection, in many cases need both: The current value and the current index.

        An example is the "Index of Maximum" problem in your web demo: You need both the current value and the current index in the loop to solve it.

        Now you can of course use a counter variable to get the index or iterate over the index and fetch the current value from the array, but since it's a very common case (I suspect I need both the current value and the index it in around 20% of all for loops over collections) it would be nice to have language support for it. The compiler can easily insert the required code only if it's used.

        Also the 'manual' version have all disadvantages:

        • The solution above needs to declare the index-variable outside the for() which pollutes the outer scope with a variable which is only needed inside the loop.
        • incrementing the index manually can lead to errors if you use continue in the loop
        • you can't declare the index variable as val

        And if you just iterate over indices and use array[i] to get the value this only works well for array lists, for other kinds of collections it can be very inefficient.

        Of course this could also solved by writing a each function which gives both value and index, but since there is a for loop in the language, I think it should be as usable as possible.

        1. Feb 03, 2012

          I suspect I need both the current value and the index it in around 20% of all for loops over collections

          I'd say that even 5% would be an exaggeration. When we figure out some really pretty syntax for indexed loops, we'll be happy to support it, but so far nothing seems goof enough.

          For the time being, I'd suggest one of the two solutions:

          forWithIndex(collection) {i, v -> 
            print("index = $i, value = $v") 
          }

          or

          for (iv in collection.indexed) { 
            print("index = ${iv.index}, value = ${iv.value}") 
          }
          1. Mar 05, 2012

            Would you like the following Syntax?

            v and i should be immutable vals inside the loop.

            1. Mar 07, 2012

              The idea is interesting, but I'm not totally convinced it adds enough value to be hard-coded in the language

      2. Feb 03, 2012

        An alternative idea for the syntax would be to use loop labels to get the current index or a boolean to return true if index==0:

      3. Mar 14, 2014

        Having the object and it's indices might not be the first use case for loops, but it feels to me like it is the second use case (for arrays and arrayLists).
        Is the 5% figure an actual computed stats on a big code base ? (say, on the kotlin coded stuff at intellij if you have tools to compute such statistics ?)
        In my code, I have quite a lot of

        Had we a syntax like

        We could write one liners instead of 3-liners like

        1. Mar 17, 2014

          for ((i, v) in array.withIndices()) { 
             // ... 
          }
  6. Apr 29, 2012

    "Note that the else branch is mandatory, unless the compiler can prove that all possible cases are covered with branch conditions."

    This is a real gem. It implies that the Kotlin compiler can determine whether you have enumerated all conditions of enum types. So now we can safely add new enum values and the compiler helps us to identify the gaps.

    Great work!

    1. May 01, 2012

      Thanks

  7. Oct 08, 2012

    Kotlin is looking very interesting indeed...

    I don't particularly want more keywords, but a very useful construct is: until (x) { } meaning the same as while (!x) { } . Found in some languages but never made it into the C family. This is usually more natural than 'while', simply because loops are often waiting for a condition to be satisfied, instead of waiting for a failed condition to disappear.

    A trivial example:

    Equally useful is do { } until (x) instead of do { } while (!x).

    1. Oct 08, 2012

      Thanks for your suggestion. I don't think these constructs are useful enough to be introduced: they make the language bigger and break the tradition, and the benefit is recognized by negligibly few people.

  8. May 16, 2013

    Hello. I've just read this article and trying when-statement myself.

    Could you please explain this:

    "
    This can be rewritten in Kotlin with as follows:

    "

    What is "Fun#(..."? Is it a tuple or special syntax to match properties of the Fun object?
    I failed to compile that code with several errors: "x is undefined" and "expected -> or when" on the '#' symbol.

    1. May 16, 2013

      It's an outdated piece of documentation. Fixed now.

  9. Jun 08, 2013

    Is there any way to check against function type in "when" statement?

    i.e.:

    1. Jun 08, 2013

      Syntax is different: (Int, Int) -> Int ("->" instead of ":"), but the compiler won't let you write such checks because they correspond to "it is Function2<Int, Int, Int>", and checks for generic types are infeasible at runtime (due to erasure).

  10. Jul 13, 2013

    Compile Error: var(and val) on loop parameter is not allowed.

    1. Jul 13, 2013

      Fixed. Thanks!

  11. Jan 30, 2014

    Would it be possible (library function ?) to have something like 

    val a : Array<String>? = null 
     
    for (string in array) { 
     
    }

    instead of 

    val a : Array<String>? = null 
     
    if (array != null) for (string in array) { 
     
    }

    Shouldn't Iterating be possible for an object with an iterator or for an object that has an iterator when it is not null ?

    Would it make sense to have this in a library or in the language ? 

    1. Jan 30, 2014

      This is debatable. We decided not to have this behaviour by default, but I think there is an orEmpty() function:

      for (a in arr.orEmpty()) {...}
  12. May 07, 2014

    I love "when", it really helps writing concise code.
    But I sometimes wish there was a way to execute some code between tests like this

    When you have lot's of tests with some conditionnal code execution in between, you have to go back to if then else and it gets quickly messy although the structure of the tests is quite simple (not nested)

    Is there something like that in Kotlin ?

    1. May 09, 2014

      You can write it like this:

      when { 
       s =="is" ->  0 
      } 
      t = s.toUpper() 
      when { 
       t == "THIS" ->  1 
       t == "HOPE" && s="less?" ->  2 
      ... 
      else -> 666 
      }

      No if-else required

  13. Jun 23, 2014

    I noticed that kotlin is moving away from iterators to streams (=lazy iterators).

    Will the containers (like arraylist) that have a iterator() method at one point implement Stream<T> ?
    At this point, the syntax looks a bit verbose :

    What are the average performance benefits of using streams/iterators over copy, is there a point (with too many composition) where these benefits disappear ?

    Do streams/iterators in kotlin take their inspiration from stuff like this http://zao.se/~zao/boostcon/09/2009_presentations/wed/iterators-must-go.pdf ?

    1. Jun 23, 2014

      It's actually

      for (s in arrayListA.stream().map {it.string} + arrayListB.stream().map {it.string}) { 
        // ... 
      }

      Collections will not implement Stream or the example above will be impossible.
      You need to put in VERY many compositions to outweigh copying a list of a few million elements.
      Streams in Kotlin are inspired by streams in Java and an obvious need in laziness

      1. Jun 23, 2014

        Many thanks for the answer. I have been developing for Android for so long that I forgot about Java 8.
        Also, I had a look at the java streams and it will make me a better developer.

        I have one last question :

        in Kotlin and Idea configured with Java 7 /android, we can already use stream()... but not parallelStream().... (maybee it is with Java 8 + kotlin ?)
        So, I'm a bit confused by what features are available or not for development with kotlin on the JVM and on Android
        Doesn't the availability of features depends on the JVM/Android version ?

        1. Jun 23, 2014

          Kotlin does not use Java 8 streams at the moment (we only have our own simplistic Stream interface), so parallelStream() is not available on any platform. When we support it in the standard library, it will be available for Java 8, but I'm not sure whether it is practical to backport streams to earlier Java versions.