Piotr Krzemiński
10/14/2025, 12:30 PM.copy(...), but without the risks of publishing it as an API and binary incompatibilities if the signature changes. Or maybe is there yet another approach?CLOVIS
10/14/2025, 12:37 PM.copy {
someField = …
}
which is much easier to guarantee binary compatibility forPiotr Krzemiński
10/14/2025, 12:40 PMPiotr Krzemiński
10/14/2025, 12:43 PMmbonnin
10/14/2025, 12:54 PMkopy focus is more on mutating nested immutable classes IIRC.Piotr Krzemiński
10/14/2025, 1:09 PMPiotr Krzemiński
10/14/2025, 1:18 PMcopy function's signature will remain the same if we e.g. add more fields. The function depends on a ...Mutable class which itself is public, but it's not intended to be used in a way other than via copy. Given that the impl of copy and the constructor's signature of ...Mutable are in sync, things should work fineCLOVIS
10/14/2025, 1:19 PMvar properties, this way the mutable class is not even part of your public API at all. If your immutable entity is an interface too, the mutable one can extend the immutable one. That is more private code, but a smaller API surface.CLOVIS
10/14/2025, 1:23 PMinterface MutableFoo {
var field1: Int
var field2: String
}
fun Foo.copy(block: MutableFoo.() -> Unit): Foo {
val result = object : MutableFoo {
override var field1 = this@copy.field1
override var field2 = this@copy.field2
}.apply(block)
return Foo(
field1 = result.field1,
field2 = result.field2,
)
}CLOVIS
10/14/2025, 1:24 PMPiotr Krzemiński
10/14/2025, 1:25 PMmbonnin
10/14/2025, 1:33 PMBuilder suffix FWIW:
Foo.copy(block: FooBuilder.() -> Unit): FooCLOVIS
10/14/2025, 2:19 PMCLOVIS
10/14/2025, 2:20 PMCLOVIS
10/14/2025, 2:20 PMxxxScope or xxxDslmbonnin
10/14/2025, 2:37 PMmbonnin
10/14/2025, 2:38 PMmbonnin
10/14/2025, 2:40 PMPiotr Krzemiński
10/14/2025, 6:38 PM