@hzsweers Thanks for the feedback!
I was wondering why the approach of all simple classes with mutable variables was taken rather than making them immutable data classes?
One of the obstacles is the fact that we plan to extend the library to other platforms in the future, thus the API of common classes cannot refer to JVM specifics (such as signature
). Currently all JVM extensions are done via Kotlin extension properties and this design seems to scale well in the presence of other platforms.
Another is performance. I agree that data classes seem nicer, but not that much nicer to justify the additional cost of all the allocations caused by mutations, and all the extra equals
/hashCode
/toString
/component
methods in the bytecode. We’re still aiming for kotlinx-metadata-jvm to be used in tools such as bytecode obfuscators and optimizers that are supposed to work fast on big codebases.
A separate question - would you be open to a PR with a non-ServiceLoader initialization option?
Yes, although I’m wondering what exactly do you have in mind. ServiceLoader seems to be the preferred way of simple DI (especially in light of the Java module system) and it should be handled properly by the Shadow plugin. In any case, let’s not discuss the details here – if you have an idea, please send a PR and I’ll take a look!
Is it possible to distinguish between receiver types and non-receiver types? For example: I don’t currently see a way to differentiate between
String.() -> Unit
and(String) -> Unit
as they’re both justFunction1<String, Unit>
as far as metadata is concerned
The way this is handled in the language is by a type annotation ExtensionFunctionType
. So the type String.() -> Unit
is actually the same as @ExtensionFunctionType (String) -> Unit
. You can find type annotations via the KmType.annotations
extension property.