Was looking at some extension methods and properties I had declared and saw something like this:
fun SomeReallyLongTypeName.method1() { ... }
fun SomeReallyLongTypeName.method2() { ... }
val SomeReallyLongTypeName.property1: SomeType get() = // ...
val SomeReallyLongTypeName.property2: SomeType get() = // ...
And was thinking about the way Dart declares extension methods (Extension methods | Dart) and in Dart extensions are always declared in an extension block. So in Dart that would be:
extension MyExtension on SomeReallyLongTypeName {
method1() { ... }
method2() { ... }
SomeType get property1 = // ...
SomeType get property2 = // ...
}
which is easier to read with less boilerplate.
Would be nice if Kotlin had a similar capability to declare a block of extensions and not have to repeat the type name over and over.
Yes using a type alias can make the name shorter, but still doesnât address the root issue. For one thing you then have the cognitive load of having to know what type the alias is referring to. If you have a lot of extensions then that alias my be hundreds of lines away. It would be more convenient and easier to read if you could declare extensions as a block
To be honest the argument that the type alias might be hundreds of lines away is also an argument against this way of declaring extensions. After all the same could be said for the top of the extension block so that would be equally far away.
Anyways, I feel like this would be most feature would be most useful for a large number of extension functions/properties that can be written as 1 liners, maybe 2-3 lines. I could see this being useful for wrapper libraries around native or java libs. Once functions get larger however I donât think that this would make much of a difference and might be even a disadvantage.
But that argument could also be made about the non-extension methods declared inside the class. The top of the class could be hundreds of lines away yet we donât have a problem in that case because we are talking about a nested context which (not sure best how to describe it) is less cognitive load. After all they could have done it like C++ where the class name has to be a prefix on every class method, but I think we would agree the ability to just nest them is easier to read.
I am not suggesting that it be required to declare them in a block, but if it were possible it could improve readability. Any feature can also be abused to decrease readability.
In Dart there is an optional name for the extension block which is used for importing the extensions so you can import all the extensions with one import.
Based on my limited experience so far, Iâm not sure how prevalent this use case is, let alone whether the prevalence/usefulness of a new feature balances out the increase in language complexity (if you have ever looked through a modern C# book, you may understand what I mean).
Anyway, at the moment I myself am not convinced that the benefits of brevity outweigh the benefits of readability and simplicity (though I guess that is ultimately for the Kotlin team to decide).
I am wondering though what the least âexoticâ/âsurprisingâ or most natural way to achieve this goal would be? âextensionâ, at the very least, does not seem a current keyword in Kotlin.
perhaps
with (String) {
fun f1() = âŠ
}
may be better⊠but if anyone has some more/better ideas about natural/easy to read/remember syntax, that may help to get this feature in.
The extension interfaces are a huge deal and shortening the name of the receiver seems irrelevant in its scope. The idea of extension interface is to be able to declare an interface (not implementation) and be able to declare types as ones having some kind of extension interface implemented on them. It is more or less the idea of KEEP-87. It requires significant design efforts.
The other possibility, as @Wasabi375 mentioned is already available. You can declare an interface or an object with member extensions and apply this object with with method. There is also a section in the KEEP-176 discussion about providing class-level receivers. It would allow avoiding those long names inside the extension class. Of course in order to do it properly, one needs full multi-receiver mechanics. In my opinion, this way is much more flexible.
I posted a similar question, and no, this issue is not addressed by type alias. In the OSS world, I canât tell how many times Iâve seen maintainers/designers slap a retort âthis is by designâ, without truly explaining the reasoning behind such a design (ternary operator, also see this for a non-Kt example), other than the obvious âIâm in the committee and youâre notâ. Swift has already been mentioned, Scala can do this too using implicit class; what is being asked here is not dissimilar to using with.
In the OSS world: fork compiler repository and try to implement it yourself, rather than whimper about designers. And you will see how itâs not easy.
One reason, for example: youâll need new keyword (âextensionâ), what can break thousands of lines in existing code.
Well I worded it as âmight be niceâ so Iâm not going off and forking the compiler. It is not a given that it would use the word âextensionâ. There are ways to do it without introducing new key words or at least introducing them in a way that it is only treated as a keyword in a certain context, i.e. a soft keyword. Here are possibilities:
MyClass companion extension {
MyClass.extension {
I am not prescribing a certain syntax, just saying it is a nice to have.
Thanks for proving my point with a new instance of âdesigner syndromeâ. In case youâve not noticed, no one is whimpering here; if youâve nothing new to add to the discussion, Iâm sure you can find other things to do.
Guys, calm down. No one here said the reason for the current state is that it is âby designâ and suggesting that doesnât help your point. It just just makes people want to engage less with the topic. So far Iâve seen some possible alternatives to this suggestion and depending on the project they might be good enough. Also passive agressive suggestions like âWhy donât you just implement it yourselfâ donât help.
Iâve seen many projects where this feature would basically do nothing at all so there is a good argument that it should be cut by the minus 100 points rule but then there are other projects where this could improve readability by a lot. Iâm not sure if the percentage of projects where this is the case is big enough that this feature is necessary, but Iâm open to adding it if there are enough people out there that like the idea. That said, you still need to convince the kotlin team because they need to implement it in the end. And only because they havenât shared their reasoning they probably discussed this idea as an alternative to the current extension function syntax (when extension functions where first implemented) so they might already have an oppinion here.
Named extension scopes that simplify import seems like an interesting aspect to me. IDEA is sometimes very slow to discover extensions for auto-completion or for auto-import, especially for infix functions. A âstar-importâ would help the IDE to find the extensions.