6

Coming from Java, I was surprised to find out that Kotlin doesn't allow assignments as expressions.

Is there a reason for that?

Java (Works)

 @Test
 public void test_x() {
 List<String> elements = null;
 for (final String x : (elements = List.<String>of("1", "2"))) {
 System.out.println(x);
 }
 }

Kotlin (Compile-time error)

 /*Assignments are not expressions, and only expressions are allowed in this context*/
 @Test
 fun test_x() {
 var elements: List<String> = listOf()
 for (x in (elements = listOf("1", "2"))) {
 println(x)
 }
 }
asked Mar 29, 2020 at 14:23
2
  • Even in the Java code you don't need the extra variable. What is the purpose of "elements"? Commented Mar 30, 2020 at 11:26
  • 2
    The example is written to demonstrate (and test) that it's compilable. Commented Mar 30, 2020 at 20:23

2 Answers 2

9

The only people who can answer this question are the designers of Kotlin. However, we can make some educated guesses:

  • Assignment is a fundamentally imperative operation. In pure functional programming, there are no assignments, in fact, the very idea of "assignment" doesn't even make sense in FP. Assignment is about changing the state of the world: before the assignment, variable foo was bound to value bar, after the assignment, it is bound to value baz. Operations that change the state of the world (e.g. printing, reading from the console), generally have a Unit or void type and/or are statements. (Depending on which one of those your programming language actually has.)
  • Accidentally assigning when you mean to test for equality, is a really common mistake. (Just within the last couple of hours, I saw at least three different questions on Stack Overflow that were caused by that mistake.) If assignments are statements, that mistake simply cannot happen.
  • Kotlin was influenced by Scala, even if in a lot of cases in how not to do things. In Scala, like several newer languages, assignments are "statements". (Technically, Scala doesn't have statements, everything is an expression, but assignments evaluate to () which is the singleton inhabitant of the Unit type which denotes a useless return value.)
answered Mar 29, 2020 at 14:38
8

Kotlin allows named arguments, which also uses the = as separator. A function fun foo(bar: Int) might be called as foo(42) or foo(bar = 42). Thus, assignment cannot occur within expressions without introducing substantial ambiguity. (Other languages can avoid this by using a different syntax for named arguments, by having a separate inline assignment operator, or by requiring inline assignments to be parenthesized, e.g. var x = 0; foo(bar = (x = 42)).)

There's also a line of thinking in functional-inspired languages that assignments are side effects and should therefore be discouraged and made more explicit. Ideally, variables are assigned exactly once, during initialization (as with Kotlin's val).

Assignments in expressions are mostly useful in control flow constructs, e.g something like while (it = next()) .... Maybe Kotlin will get suitable syntax in the future.

answered Mar 29, 2020 at 14:40

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.