# Add ternery operator

**URL:** <https://discuss.kotlinlang.org/t/add-ternery-operator/29408>\
**Category:** Language Design\
**Created:** [October 17, 2024, 4:09am UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408 "2024-10-17T04:09:51Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![minglei.lee](https://avatars.discourse-cdn.com/v4/letter/m/a587f6/32.png) [@minglei.lee](https://discuss.kotlinlang.org/u/minglei.lee)\
**Post date:** [October 17, 2024, 4:09am UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/1 "2024-10-17T04:09:51Z")

</div>

I love Kotlin, it’s so neat and elegant. 👍 👍 👍

When I learned about Kotlin a few years ago, I was surprised to find that I couldn’t write `a ? b : c`, which is common in many other languages. Of course, I can use `if (a) b else c` instead, but it’s not neat.

After using Kotlin for a few years, I still think that the ternary operator should be supported. It’s the only obvious disadvantage I can think of (compared to Java).

I noticed [this](https://discuss.kotlinlang.org/t/ternary-operator/2116/122) post, but it’s closed. Hope the ternery operator can be reconsidered.

---

<div class="post-metadata">

**Author:** ![dalewking](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dalewking/32/1496_2.png) [@dalewking](https://discuss.kotlinlang.org/u/dalewking)\
**Post date:** [October 17, 2024, 4:35am UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/2 "2024-10-17T04:35:30Z")

</div>

Been, discussed to death in many other threads. It ain’t gonna happen, thank goodness.

---

<div class="post-metadata">

**Author:** ![dalewking](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dalewking/32/1496_2.png) [@dalewking](https://discuss.kotlinlang.org/u/dalewking)\
**Post date:** [October 17, 2024, 5:03am UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/3 "2024-10-17T05:03:04Z")

</div>

I will say however here is a utility method I created for our code base that comes in handy sometimes:

```auto
inline fun <T> Boolean.map(ifTrue: T, ifFalse: T) =
    if (this) ifTrue else ifFalse

```

which allows you to say

```auto
    a.map(b, c)

```

though it may not cover all cases

---

<div class="post-metadata">

**Author:** ![minglei.lee](https://avatars.discourse-cdn.com/v4/letter/m/a587f6/32.png) [@minglei.lee](https://discuss.kotlinlang.org/u/minglei.lee)\
**Post date:** [October 20, 2024, 4:08am UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/4 "2024-10-20T04:08:22Z")

</div>

Yes, it’s not ideal because `b` and `c` will always be evaluated.

---

<div class="post-metadata">

**Author:** ![chikega](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/chikega/32/9382_2.png) [@chikega](https://discuss.kotlinlang.org/u/chikega)\
**Post date:** [October 20, 2024, 12:52pm UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/5 "2024-10-20T12:52:07Z")

</div>

I do like the C-based conditional ternary operator. But, there are actually more languages that do not support it - such as some recent ones (eg. Rust, Julia, Nim and Crystal) and older popular ones like Python and Lua. Scala which inspired some aspects of Kotlin also chose not to implement it either.

1. Python
2. Rust
3. Crystal
4. Nim (though it has a similar construct)
5. MATLAB
6. Pascal
7. COBOL
8. Fortran
9. Lua
10. Julia
11. Erlang
12. Elixir
13. Ada
14. Modula-2
15. R
16. TCL
17. Smalltalk
18. Prolog
19. Bash and most shell scripting languages
20. Scratch
21. Scala
22. Kotlin

Lisp family:  
23. Common Lisp  
24. Emacs Lisp  
25. AutoLisp  
26. Clojure  
27. ISLISP  
28. PicoLisp  
29. newLisp

Scheme family:  
30. Racket  
31. Chez Scheme  
32. Chicken Scheme  
33. Gambit  
34. Guile  
35. MIT Scheme  
36. Bigloo  
37. Kawa

Forth family:  
38. ANS Forth  
39. fig-Forth  
40. iForth  
41. SwiftForth  
42. gForth  
43. pForth  
44. ColorForth  
45. 8th

BASIC family:  
46. Visual Basic  
47. VBScript  
48. B4X (B4A, B4i, B4J, B4R)  
49. QBasic  
50. FreeBASIC  
51. PureBasic  
52. Liberty BASIC  
53. SmallBASIC  
54. BBC BASIC  
55. Gambas

ML family:  
56. Standard ML  
57. OCaml  
58. F#

Hardware Description Languages:  
59. VHDL  
60. Verilog

1. ABAP
2. Logo
3. Alice
4. Inform 7
5. APL
6. J
7. Occam
8. Oberon
9. Io
10. Eiffel
11. Mathematica/Wolfram Language
12. LabVIEW
13. REXX
14. PL/I
15. Algol
16. Simula
17. Maple
18. Ladder Logic (used in PLCs)

---

<div class="post-metadata">

**Author:** ![dalewking](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dalewking/32/1496_2.png) [@dalewking](https://discuss.kotlinlang.org/u/dalewking)\
**Post date:** [October 24, 2024, 3:03pm UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/8 "2024-10-24T15:03:35Z")

</div>

Yeah, I generally only use it for things that are not computed. Most often for choosing between 2 string resources for the UI based on a boolean such as this other function I have:

```auto
val Boolean.toYesNo: StringDesc get() = map(yes_label, no_label)

```

---

<div class="post-metadata">

**Author:** ![digorydoo](https://avatars.discourse-cdn.com/v4/letter/d/df788c/32.png) [@digorydoo](https://discuss.kotlinlang.org/u/digorydoo)\
**Post date:** [November 29, 2025, 9:09am UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/9 "2025-11-29T09:09:52Z")

</div>

My two cents: As Kotlin uses `?` to express nullability and has a `?:` operator, the usual `c ? a : b` would not feel right. However, what makes the expression `if (c) a else b` slightly hard to read is that `c` is separated from `a` only via the closing parenthesis. We could improve this and make it more readable if we allowed dropping the parentheses and adding a `then` instead:

```auto
val z = if (c) a else b
val z = if c then a else b

```

It reads particularly better if expressions are long and need to be wrapped:

```auto
val z = if (someLongish < condition)
   someLongishA()
else
   someLongishB()

val z = if someLongish < condition
   then someLongishA()
   else someLongishB()

// Or:
val z =
   if someLongish < condition
   then someLongishA()
   else someLongishB()

```

---

<div class="post-metadata">

**Author:** ![gidds](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/gidds/32/10865_2.png) [@gidds](https://discuss.kotlinlang.org/u/gidds)\
**Post date:** [November 30, 2025, 10:43pm UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/10 "2025-11-30T22:43:50Z")

</div>

> [@digorydoo](#):
>
> dropping the parentheses and adding a `then` instead

That has several minor disadvantages; but worse, it doesn’t _look_ like Kotlin. Every other conditional in Kotlin uses parens — `when`, `while`/`do`…`while`, params to functions like `require()`, etc. Dropping them for this one case would be inconsistent and confusing.

Also: it gets very confusing if you need to nest conditions. And it doesn’t work so well for multi-way `if`s:

```kotlin
if someLongish < condition
then someLongishA()
else if someOther < condition
    then someLongishB()
    else someLongishC()

```

(You could drop the indentation, but it’s still confusing having some `else` lines followed by conditions and others by values.)

I suppose you could keep the parens but allow `then` to be used — but does that give much benefit in the single-line case?

(Also, after almost 15 years, many people and organisations have significant investment in Kotlin code, so it’d have to be optional to avoid breaking existing code.)

---

<div class="post-metadata">

**Author:** ![digorydoo](https://avatars.discourse-cdn.com/v4/letter/d/df788c/32.png) [@digorydoo](https://discuss.kotlinlang.org/u/digorydoo)\
**Post date:** [December 1, 2025, 5:47am UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/11 "2025-12-01T05:47:55Z")

</div>

Don’t break existing code. Make it optional. If you like the parentheses, you can still use them.

This is about the ternary operator. Your example is just a normal if statement. Of course, you could also use “then” there, but that’s off the point.

The ternary operator is confusing when using for nested conditions. See discussions on prettier for JavaScript/TypeScript. The least confusing formatting is IMO like this:

```javascript
const r = 
   c1 ? a
   : c2 ? b
   : c3 ? c
   : d;

```

Which could be written as:

```auto
// current Kotlin
val r =
   if (c1) a
   else if (c2) b
   else if (c3) c
   else d

// proposed syntax
val r =
   if c1 then a
   else if c2 then b
   else if c3 then c
   else d

```

I find the proposed syntax slighty better to read. But by all means make it optional.

Anyway, for nested ifs, it’s better to use when probably.

```auto
val r = when {
   c1 -> a
   c2 -> b
   c3 -> c
   else -> d
}

```

With other words, the ternary operator isn’t the best choice for situations that need nested condition checks, and Kotlin already has a when statement. The ternary operator is very handy for cases when a single if statement is inlined in an expression, and the existing if in Kotlin is just slightly harder to read IMO, but adding `then` could make improve it. But it’s a matter of taste, of course.

And yes, for consistency, it should then also be allowed to drop the paretheses with `while` and `for` loops. That doesn’t look like current Kotlin, but does that make it bad? (The only bad thing I see that it would create inconsistency in coding style across the community.)

---

<div class="post-metadata">

**Author:** ![digorydoo](https://avatars.discourse-cdn.com/v4/letter/d/df788c/32.png) [@digorydoo](https://discuss.kotlinlang.org/u/digorydoo)\
**Post date:** [December 1, 2025, 6:00am UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/12 "2025-12-01T06:00:30Z")

</div>

Here’s a better example why I think `then` could improve the readability:

```auto
return if (a * x + b * y < c * z) (t - t0) * (q - p0)
   else (t + t0) * (q - p1)

// Or
return if a * x + b * y < c * z then (t - t0) * (q - p0)
   else (t + t0) * (q - p1)

// Or, since parentheses are optional in this proposal
return if (a * x + b * y < c * z) then (t - t0) * (q - p0)
   else (t + t0) * (q - p1)

```

In the existing parentheses-based syntax, the place where the condition ends and the statement starts is not easily seen. Of course, you could add `{}` braces, but that forces newlines with some formatters.

This example also makes it clear that dropping the parentheses is not a big deal. The thing that makes it easier to read is the proposed optional `then`.

---

<div class="post-metadata">

**Author:** ![Ries\_Twisk](https://avatars.discourse-cdn.com/v4/letter/r/96bed5/32.png) [@Ries\_Twisk](https://discuss.kotlinlang.org/u/Ries_Twisk)\
**Post date:** [December 3, 2025, 7:47pm UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/13 "2025-12-03T19:47:43Z")

</div>

This is a perfect example why a ternary operator would read better.. but yeaaaa.. kotlin designers are stubborn…

---

<div class="post-metadata">

**Author:** ![Skater901](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/skater901/32/10163_2.png) [@Skater901](https://discuss.kotlinlang.org/u/Skater901)\
**Post date:** [December 4, 2025, 2:44am UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/14 "2025-12-04T02:44:36Z")

</div>

I guess this is just my opinion, but I think that a ternary is most valuable when the whole expression fits on one line. As soon as you start splitting it across multiple lines, imo an `if` expression looks better. idk if you’ve deliberately split it, or if that’s just how the forum has formatted it, but I would go all the way and fully separate it out, like so:

```kotlin
return if (a * x + b * y < c * z)
        (t - t0) * (q - p0)
   else
        (t + t0) * (q - p1)

```

---

<div class="post-metadata">

**Author:** ![sylvainspinelli](https://avatars.discourse-cdn.com/v4/letter/s/0ea827/32.png) [@sylvainspinelli](https://discuss.kotlinlang.org/u/sylvainspinelli)\
**Post date:** [December 4, 2025, 7:24am UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/15 "2025-12-04T07:24:29Z")

</div>

In my case I dislike when I’m not sure if a line is a real new line of code or not (without reading the entire previous line).

So I dislike:

```kt
if (aLongTest(p1, p2) && reallyLong() && (a * x + b * y < c * z))
	doSomething()

```

This syntax would be realy more readable for me

```kt
if aLongTest(p1, p2) && reallyLong() && (a * x + b * y < c * z)
	then doSomething()

```

And of course for ternary operator, it would also be much clearer.

```kt
val x = if aLongTest(p1, p2) && reallyLong() && (a * x + b * y < c * z)
	then doSomething()
	else doSomethingElse()

```

---

<div class="post-metadata">

**Author:** ![digorydoo](https://avatars.discourse-cdn.com/v4/letter/d/df788c/32.png) [@digorydoo](https://discuss.kotlinlang.org/u/digorydoo)\
**Post date:** [December 6, 2025, 11:12am UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/16 "2025-12-06T11:12:07Z")

</div>

Another example:

```auto
// C++
auto x = fn(px * qx + py * qy > 0 ? (a - b) * t : (a + b) * t);

// Current Kotlin, single line
val x = fn(if (px * qx + py * qy > 0) (a - b) * t else (a + b) * t)

// Current Kotlin, multi-line
val x = fn(
   if (px * qx + py * qy > 0)
      (a - b) * t
   else
      (a + b) * t
)

// Proposal
val x = fn(if px * qx + py * qy > 0 then (a - b) * t else (a + b) * t)

```

The C++ version is easy to read, because the question mark separates the condition from the value.

The single line version of current Kotlin is hard to read, because there is no such delimiter.

The multi-line version is easy to read, but it’s, well, multi-line. It looks much more verbous than the C++ variant.

The proposal is close to the C++ variant and is easy to read IMO.

---

<div class="post-metadata">

**Author:** ![Skater901](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/skater901/32/10163_2.png) [@Skater901](https://discuss.kotlinlang.org/u/Skater901)\
**Post date:** [December 8, 2025, 9:17am UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/17 "2025-12-08T09:17:11Z")

</div>

I gotta disagree, the C++ version is NOT easy to read, lol. Out of all of those examples, I like the multi line one the best. It separates it out perfectly so that I can consider each part in isolation.

Though I have to ask, is this actually a real example? Because it seems like very unreadable code, what with the short variable names and multiple mathematical operations. I think the lack of ternary is less of an issue than the code itself.

---

<div class="post-metadata">

**Author:** ![dalewking](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dalewking/32/1496_2.png) [@dalewking](https://discuss.kotlinlang.org/u/dalewking)\
**Post date:** [December 20, 2025, 8:22pm UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/18 "2025-12-20T20:22:37Z")

</div>

> [@Skater901](#):
>
> ```auto
> return if (a * x + b * y < c * z)
> (t - t0) * (q - p0)
> else
> (t + t0) * (q - p1)
> 
> ```

Or better yet:

```auto
return when {
    a * x + b * y < c * z -> (t - t0) * (q - p0)
    else -> (t + t0) * (q - p1)
}

```

but much of the reading difficulty here is the expressions you are using, not if vs. ternary

---

<div class="post-metadata">

**Author:** ![Skater901](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/skater901/32/10163_2.png) [@Skater901](https://discuss.kotlinlang.org/u/Skater901)\
**Post date:** [December 21, 2025, 5:35am UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/19 "2025-12-21T05:35:52Z")

</div>

I actually don’t like that `when` version haha, it has the same problem as the two line `if else` in that the condition and the first case are on the same line, so I’m still parsing through a bunch of \* and + and \< and () and - looking for the `->` that denotes the separation between the condition and the case.

---

<div class="post-metadata">

**Author:** ![digorydoo](https://avatars.discourse-cdn.com/v4/letter/d/df788c/32.png) [@digorydoo](https://discuss.kotlinlang.org/u/digorydoo)\
**Post date:** [December 21, 2025, 10:35am UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/20 "2025-12-21T10:35:24Z")

</div>

I just realised we can do this in current Kotlin:

```auto
class Given(val left: T, val condition: Boolean)

infix fun <T> T.given(condition: Boolean) = Given(this, condition)
infix fun <T> Given.otherwise(right: T) = if (condition) left else right

fun main() {
   println(4.2f given true otherwise 8.5f)
   println(4.2f given false otherwise 8.5f)
   println((a - b) * t given (px * qx + py * qy > 0) otherwise (a + b) * t)
}

```

This is both so cool and so obvious that other people will probably already have implemented this. The only small issue here is that I can’t use `else` , I had to introduce `otherwise`.

---

<div class="post-metadata">

**Author:** ![digorydoo](https://avatars.discourse-cdn.com/v4/letter/d/df788c/32.png) [@digorydoo](https://discuss.kotlinlang.org/u/digorydoo)\
**Post date:** [December 21, 2025, 11:19am UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/21 "2025-12-21T11:19:45Z")

</div>

My excitement has somewhat faded. Both sides are always evaluated, independent of the condition. This is not how an `if` statement should work. Also, if the two sides don’t have the exact same type, Kotlin is unable to infer the supertype.

```kotlin
open class Mock(val value: Int)

class Mock1(sideEffect: (who: String) -> Unit): Mock(1) {
    init {
        sideEffect("Mock1")
    }
}

class Mock2(sideEffect: (who: String) -> Unit): Mock(2) {
    init {
        sideEffect("Mock2")
    }
}

@Test
fun `should work as expected when left and right are both of different types`() {
    val called = mutableListOf<String>()
    val sideEffect = { who: String -> called.add(who); Unit }

    // Unfortunately, Kotlin can't infer that the supertype Mock satisfies the
    // constraints without an explicit cast.
    val m1 = Mock1(sideEffect) as Mock given true otherwise Mock2(sideEffect)
    assertIs<Mock1>(m1) // condition was true, we get the left value
    assertIsNot<Mock2>(m1)

    // Unfortunately, Mock2 was created even though it was not used in the end.
    assertEquals("Mock1, Mock2", called.joinToString(", "))

    called.clear()

    val m0 = Mock1(sideEffect) as Mock given false otherwise Mock2(sideEffect)
    assertIsNot<Mock1>(m0) // condition was true, we get the right value
    assertIs<Mock2>(m0)

    // Same here: Both sides are always evaluated.
    assertEquals("Mock1, Mock2", called.joinToString(", "))
}

```

---

<div class="post-metadata">

**Author:** ![Landei](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/landei/32/9407_2.png) [@Landei](https://discuss.kotlinlang.org/u/Landei)\
**Post date:** [December 21, 2025, 1:21pm UTC](https://discuss.kotlinlang.org/t/add-ternery-operator/29408/22 "2025-12-21T13:21:47Z")

</div>

Of course you need lambdas if you want to defer evaluation:

```kotlin
class Given<T>(val left: () -> T, val condition: Boolean)

infix fun <T> (() -> T).given(condition: Boolean) = Given(this, condition)
infix fun <T> Given.otherwise(right: () -> T) = if (condition) left() else right()

fun main() {
    println({4.2f} given true otherwise {8.5f})
    println({4.2f} given false otherwise {8.5f})
}

```

[Next page](https://discuss.kotlinlang.org/t/add-ternery-operator/29408.md?page=2)
