https://kotlinlang.org logo
#language-proposals
Title
# language-proposals
l

Laxystem

10/24/2023, 12:53 PM
Planning to create a keep for Extension Constructors.
Copy code
class Foo(bar: String)
// three mentions of Foo in explicit api! Java interop is horrible! The IDE doesn't know this is a constructor, complains about the naming, and stylizes incorrectly!
fun Foo(bar: Int?): Foo = Foo(bar.toString())

// An extension secondary constructor! Java thinks it's a static method named "fooOf".
Foo.constructor(bar: Int?) : this(bar.toString())

// Alternate syntax
constructor Foo(bar: Int?) : this(bar.toString())

// And extension "inner" classes, for free!
context(String)
Foo.constructor() : this(this@String)
1
a

Ayfri

10/24/2023, 4:30 PM
What difference would this have compared to creating a function with the same name as the class ?
3
l

Loney Chou

10/24/2023, 5:09 PM
IMO "constructor" shouldn't be a concept outside the class... also constructor is pretty limited in respect to functionality. You can't
inline
(which means you can't have
reified
or low-cost lambda), you must call
this()
first (which means you can't have elegant parameter validation).
1
s

stantronic

10/24/2023, 7:06 PM
what would happen if someone defined an
operator fun invoke(bar: Int?)
on Foo.companion? which would get called when I do Foo(5) ?
d

Derek Peirce

10/25/2023, 6:16 AM
Presumably
invoke
would be called, which is the same thing that already happens when someone adds a method to a base class with the same signature as your extension method.
b

Ben Woodworth

10/25/2023, 7:31 AM
I'm a fan of the
invoke
approach because it gets treated the same as constructors in the IDE (which isn't that strong of a reason I suppose) and doesn't fill the intellisense with overloads like functions to. Plus it's linked more explicitly at the language level so e.g. refactorings are guaranteed to work without having to special case check that same-named functions are also updated. In the future it should also be possible to use
invoke
for classes without companion objects with static extensions
l

Laxystem

10/29/2023, 1:34 PM
@Ayfri Java will be able to see the function as
fooOf()
instead of
Foo()
(which looks weird, as Java uses the
new
operator) without declaring an explicit
@JvmName
, and more importantly - you won't need to repeat the name of the extended class three times when using explicit API.
@stantronic exactly the same as in any other case where there are multiple functions available and the compiler cannot determine which should be used.
The
invoke
approach is nice, yet:
Copy code
operator fun Foo.Companion.invoke(): Foo = Foo()
//           1                       2     3

void main() {
    FooKt.invoke(FooKt.Foo.Companion); // invoke functions
    FooKt.fooOf(); // extension constructors
}

// plus, the IDE still doesn't recognize a constructor use and cannot style it like "normal" constructors.
As for `inline`ing, I believe there's no reason not to allow an inlined extension constructor - it could be a great use-case. As for having to call
this()
, I assume one could just allow extension constructors not to "extend" a constructor if they call it.