question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

‘if … else if’ expression unexpectedly has Unit value when last branch taken

See original GitHub issue

Compiler version

3.1.1

Minimized code

This code prints (), as a evaluates to the Unit value:

 val a =
    if false then
       1
    else if true then
       2
 
 println(a)

Update: this code may be a bit too minimized to demonstrate the scope of the actual problem. See the examples in this comment for more clarity.

Output

()

Expectation

Although this code is unusual and unlikely to be written by an experienced programmer (it is a simplified and minimized version of something written by my 8-year-old son who has just started learning to program with Scala), I suspect most people would intuitively expect a to evaluate to 2 rather than to ().

Adding an unconditional else clause to the if statement restores expected behaviour:

val a =
    if false then
       1
    else if true then
       2
    else
       3
 
 println(a) // prints 2

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:13

github_iconTop GitHub Comments

1reaction
som-snyttcommented, Apr 13, 2022

@KacperFKorban hi, if you agree, would you mind reopening? My previous judgment may have been premature. Or, we could start a discussion in discussions.

1reaction
som-snyttcommented, Apr 13, 2022

That’s pretty funky. Just the penultimate branch (before the missing else) gets its value discarded (as I now see you said). That must be a glitch.

➜  dotty git:(test/current) ./bin/scala -Vprint:parser,typer
Welcome to Scala 3.1.3-RC1-bin-SNAPSHOT-git-f3cca47 (17.0.2, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.

scala> def f(x: String) = {
     |   if x == "1" then 1
     | }
[[syntax trees at end of                     typer]] // rs$line$1
package <empty> {
  final lazy module val rs$line$1: rs$line$1 = new rs$line$1()
  final module class rs$line$1() extends Object() { this: rs$line$1.type =>
    def f(x: String): Unit =
      {
        if x.==("1") then
          {
            1
            ()
          }
         else ()
      }
  }
}

1 warning found
def f(x: String): Unit
-- [E129] Potential Issue Warning: ------------------------------------------------------------------------------------------------------
2 |  if x == "1" then 1
  |                   ^
  |                   A pure expression does nothing in statement position; you may be omitting necessary parentheses
  |
  | longer explanation available when compiling with `-explain`

scala> def f(x: String) = {
     |   if x == "1" then 1
     |   else if x == "2" then 2
     |   else if x == "3" then 3
     | }
[[syntax trees at end of                     typer]] // rs$line$2
package <empty> {
  final lazy module val rs$line$2: rs$line$2 = new rs$line$2()
  final module class rs$line$2() extends Object() { this: rs$line$2.type =>
    def f(x: String): AnyVal =
      {
        if x.==("1") then 1 else
          if x.==("2") then 2 else
            if x.==("3") then
              {
                3
                ()
              }
             else ()
      }
  }
}

1 warning found
def f(x: String): AnyVal
-- [E129] Potential Issue Warning: ------------------------------------------------------------------------------------------------------
4 |  else if x == "3" then 3
  |                        ^
  |                        A pure expression does nothing in statement position; you may be omitting necessary parentheses
  |
  | longer explanation available when compiling with `-explain`

scala>
Read more comments on GitHub >

github_iconTop Results From Across the Web

Why Kotlin compiler gives an error in a valid IF statement?
It REQUIRES a return value from within the lambda, and last statement inside it is when block so it is used as an...
Read more >
Missing "else" changes branch percentage #35 - GitHub
This is a feature. It tells you that you don't have a test case where the "empty else block that notionally exists" is...
Read more >
C#'s cascaded if statement: evaluate multiple conditions
C#'s cascaded if statement evaluates a series of true/false expressions. The one that's true has its code block execute.
Read more >
Comp Sci Chapter 4 Flashcards - Quizlet
The last branch is not just "else" but has an expression. nested if-else statements. The first branch executes, which is a nested if-else....
Read more >
If Statements, Loops and Recursions · OCaml Tutorials
If statements (actually, these are if expressions). OCaml has an if statement with two variations, and the obvious meaning: if boolean- ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found