Hmm. I'm disappointed in kotlinc compiler magic. ...
# announcements
g
Hmm. I'm disappointed in kotlinc compiler magic.
Copy code
do {
  val x = true
}
while(x)
works but
Copy code
do try {
  val x = true
}
finally {}
while(x)
does not. Can i log this as a bug? Or an enhancement?
g
do you mean this?
Copy code
do {
        try {
            val x = true
        } finally {

        }
    } while (x)
}
e
Kotlin parser is designed with a particular code formatting in mind. If you format your code according to Kotlin code style, then it all works. In particular, both
while
and
finally
shall be written on the same line as closing curly brace.
p
I guess @groostav wants to access variable
x
outside of
try
block where it is declared. But this is not possible as variable is only visible inside scope where it is declared. So solution would be to declare variable
x
outside of
try
block.
Copy code
do {
    val x: Boolean
    try { 
        x = true
    } finally { 
    }
} while (x)
I would suggest to rewrite code to make
try
an expression if possible:
Copy code
do {
    val x = try { 
        true
    } finally {
        false
    }
} while (x)
g
@Pavlo Liapota that is my workaround, but it kinda defeats the purpose of the magic in the first place. The magic is that the kotlin compiler is able to infer declared variables in hte body of a
do
block, and use them for the conditional expression in the
while
statement. Its a neat trick. Unlike the smart-casting or type-casting tricks however, this trick is not able to see through
inline
functions (or similar), because... well because the kotlin compiler team has a finite number of hours to work. Still, it does seem like a limitation more than a design choice.
and yeah @elizarov, the problem is not formatting,
Copy code
do {
  try {
    val x = true;
  }
} while(x)
also does not work. The problem is the compilers ability to lift the variable
x
through the
try
block. It wont do it.
p
Condition of
do-while
statement is located in the same scope as statement body, that’s why variable declared in a body can be access in condition expression. While
try
,
if
, lambdas, etc. create new scopes. Consider example:
Copy code
if (foo) {
    val x = true
} else {
    val x = false
}
You don’t expect variable
x
to be visible outside of
if
block, right?
Also capturing
when
feature was added exactly because people didn’t want to pollute scope with temporary variable declaration:
Copy code
val a = func() // a is accessible after when block
when (a) {
    // ...
}
Copy code
when(val a = func()) { // a is not accessible after when block
    // ...
}
e
@groostav thanks for clarification. I did not understand what was the original problem. The scoping rules are deliberate design decisions, though.