Proposal: Add ability to add "extensions" to a "ty...
# language-proposals
r
Proposal: Add ability to add "extensions" to a "type" for a cleaner reified use. For example, it's now possible to define a function like
inline fun <reified T: Application> launch() = Application.launch(T::class.java)
which can be used like
launch<MyApp>()
. It would be pretty slick if you could instead do something like
MyApp.lauch()
that would do the exact same thing. This is a very minor thing with very little benefit over looks, but I figured I'd suggest it. Before any one suggests it, no, companion objects won't solve the problem as this needs to be generic.
j
Doesn't changing the signature to
T.launch
solve this?
Oh I see. You want to call it without an instance.
👍 2
In the past I've then put the extension on
KClass<T>
so it becomes
MyApp::class.launch()
I'm generally upset that
KClass<T>
and
T.Companion
don't refer to the same instance.
r
Indeed, there are plenty of workarounds (like the one I mentioned). It would just look so clean to use the reified type as the receiver. Not a big concern though.
h
I think the usecase is one mentioned often times here https://github.com/Kotlin/KEEP/pull/87
r
I may be missing something, but I don't think so.
l
You can make the companion object extend an abstract/open class or implement an interface (including by delegation). That's what I do here for Android Activities, Services and BroadcastReceivers: https://github.com/LouisCAD/Splitties/tree/master/modules/intents
r
Called it 🙂
l
Downside is you need to declare it explicitly. Upside is it is declared explicitly (so no way to have it compile on the wrong type).
r
What Type classes in KEEP 87 proposed is this but ad hoc for any type you don’t own when you don’t have the ability to alter it’s subtype hierarchy. The proofs and type classes support in Meta coming up in 1.4 gives you this ability of project families of extension functions over any arbitrary type as if the type in the left extends the one in the right
Copy code
//given provider proofs Unit(truth) -> App, object, val and class also supported
@given fun app(): App = MyApp() 

//given summons coherent provider in the classpath in any expression position not just contructors or args
fun MyApp.Companion.launch(app: App = given()) = app.reallyLaunch() 

MyApp.launch() // runs with coherent provider app()
MyApp.launch(testApp) //runs with local override testApp
No reified types or inlining really required since this is solved in the type-checking phase in resolution and call sites get their values injected. While the original description of Keep 87 did not have implicits, Arrow Type Proofs have given coherent implicits, extension projections, coercion functions, union types and type refinements that are verified at compile time. Just waiting for 1.4 to stabilize to launch the first preview release and some more KEEPs for each of the features in case others in the lang are interested I stopped discussing in the KEEP because it got a lot of traction but no official response and I get why, it became controversial at some point with so many design opinions and choices. I really don’t know how KEEPs are supposed to work.