Other (even closer) approximation of aforementioned kotlin’s code may look like this
// this is valid code which was checked to be working under current state of 'add-extensions' branch
object TestMain {
def main(args: Array[String]): Unit = {
testFooBarBuilder2()
}
// marker interface used as "dummy" target for extension methods
trait FooBarDslNsActivator
case class FooBar(val foo: Int, val bar: Int)
case class FooBarBuilder(var foo: Int = 0, var bar: Int = 0) {
// this builder methods are theoretically defined as extension methods of (object `this`)
def initFoo(this __ : FooBarDslNs)(foo: Int): Unit = {
this.foo = foo
}
def initBar(this __ : FooBarDslNs)(bar: Int): Unit = {
this.bar = bar
}
def init(initBlock: implicit FooBarBuilder => Unit): this.type = {
//implicit val `import this`: FooBarBuilder = this
initBlock(this)
this
}
def build(): FooBar = FooBar(foo, bar)
}
object testFooBarBuilder2 extends FooBarDslNsActivator {
def apply(): Unit = {
val builder = FooBarBuilder()
builder.init {
// `this.initFoo(10)` from kotlin's example will have exactly the same side effect on builder
this.initFoo(10)
// `this.initBar(20)` from kotlin's example will have exactly the same side effect on builder
this.initBar(20)
// unfortunately `this.initFoo(10)` !== `initFoo(10)` for extension method `initFoo`
// in current implementation of extension methods resolving
}
val fooBar = builder.build()
assert(fooBar.foo == 10)
assert(fooBar.bar == 20)
println(fooBar)
}
}
}