Initializing vals in closure?


#1

Hi,

I asked about this a while ago (old post). Curious if anything has changed, as I’m cleaning up some old code.

Basically, can I tell it that x is safely initialized?

fun help(f: () -> Unit) { f() }

class Foo {
    val x: Int
    init {
        help {
            x = 10
        }
    }
}

#2

I don’t think so.
Within class “Foo”, you have no clue what “help” function is going to do with your lambda. Maybe help function never executes the given lambda (f). So the compiler complains about “x” not being initialized.


#3

Not allowed under any circumstances at the moment.

This may be supported some time later for the case when help is inlined. That is, if we get around to “seeing through” inilne function bodies"


#4

I could file a feature request, if you think it’s possible and worth considering an attribute that the compiler checks, like:

fun help(@mustcall f: () -> Unit) { ... }

Meaning: if help doesn’t throw, f was called.

The builder pattern is such a nice feature for building UI component classes, but without this my constructors can be a bit awkward.

Rob


#5

For a signature like that, could you maybe change it to pass through the return value?

x = help { 10 }

for instance.


#6

Unfortunately, in the real code the body is creating UI structures like HTML DOM elements, and setting a number of instance variables (not just one, like my example) to pieces of the DOM.

Rob