https://kotlinlang.org logo
#feed
Title
# feed
m

marcinmoskala

07/20/2021, 6:03 AM
Effective Kotlin Item 46: Avoid member extensions https://kt.academy/article/ek-member-extensions
❤️ 2
👎 1
👏 3
t

Tyler Hodgkins

07/20/2021, 4:00 PM
B-b-but… what about my DSL? 😂
😂 2
p

pepos

07/20/2021, 6:17 PM
“Even though it is possible, there are good reasons to avoid defining member extensions (except for DSLs).”
👍 1
you are fine 😂
h

Hanno

07/20/2021, 9:15 PM
unpopular opinion incoming, The example using let instead of a member extension is just plain ugly and unnecessary...
The visibility example is also bad, because member extensions can also be just made private and visibility would be solved.. I really dislike this article is on kt Academy, its going to get me a lot of discussions because people will follow it blindly
m

marcinmoskala

07/21/2021, 7:45 AM
I respect every opinion. Ugly does not seem like something anyone can discuss, how about considering practical? I lay down arguments why I find member extensions problematic. Comparing to
let
, isn't it more explicit, like
.map { process(it) }
instead of
.processElemens()
? Don't you find it confusing, when extensions are inside classes, and you don't know if they are extending functionality, of if they are just another method? Just to make it clear, it is not originally my suggestion. I first heard it on the first influential presentation about the topic - Idiomatic Kotlin:

https://www.youtube.com/watch?v=CJQ7JbwV8FY

Then repeated by many others, for instance here on KotlinConf:

https://www.youtube.com/watch?v=ihdEjDoXOgc

Although just because this argument is repeated, doesn't make it true. I understand, that if this pattern is used many times, people might get used to it so much, that their understanding changed, they adjusted practices to it, and it might be perfectly fine. I would be happy to hear what other thinks about it?
h

Hanno

07/21/2021, 7:20 PM
Thanks for your respect, i also have respect, but i am also honest and direct: when we have to discuss why number.isPhoneNumber is better than number.let(::isPhoneNumber) than this discussion will be very complicated. One thing (dot notation) is (probably) the most well known pattern in programming after function call syntax and variable declaration, thats why kotlin allows for extensions, to enable dot notation. The other thing needs higher order functions, kotlin specific scoping functions from the std, while the let keyword is not THAT well known, a callable reference that is also not as common as a dot notation, additional double colons, two brackets.... Your example with processElements and forEach is comparing two really different api levels. When you have a typeclasses like Class that can process a list of specific elements, then it would be preferable to implement a process method on a collection of said elements as an api for the user, just as required. Explicit or not is not really the question. Urging the user to explicitly write the iteration by himself is valid, but that should be a api design question: should the user so the iteration himself? Hint, hiding it from the call site enables changing the implementation for example. So from my pov it really boils down to a single situation that is problematic, which is also one of your examples: shadowing. I understand the problem, i accept it, but i dont think its about member extensions... Because its the problem with every single scope in the language, be it top level vs local, be it class level vs local, be it parameter vs class level... We dont ditch all those concepts either, do we?
1
m

marcinmoskala

07/22/2021, 12:07 PM
There are some general rules that seems to be working well. We prefer less mutability over more. Less visibility. Less meanings of receiver. What does not stop us from using mutability, public elements, new receivers etc. when there is a reason for that. Just because problems with mutability exist in every language, we should not stop trying to prevent them by less and smarter mutability. The same with receiver.
h

Hanno

07/22/2021, 10:57 PM
I think you didnt get my point, i just showed that its not about receivers really, but about a single situation, shadowing. Its the only case where it even matters ... The article shows a trivial example where variable names and types are the same. I really really doubt the real world relevance of such an example, this will almost never happen in real projects, and if it does, the code can probably be made better and the Problem just disapears. I find it really Strange to conclude that member extensions should be generally avoided while there is only a single situation that doesnt happen all too often where there might be a problem.
n

Nick Allen

07/30/2021, 6:55 PM
As far as I can tell, neither video really supports the argument that member extensions should be avoided. Seems like the first video says not to use them if you don't need them (extension on the same class or no state is used at all) but seems to encourage their use if appropriate (needs enclosing class's state). The second video seems to not mention member extensions at all (maybe I just missed it scanning through) but rather warns against turning every single-argument method into an extension method.
❤️ 1
I'd avoid public member extensions, but I don't recall much confusion resulting from the use of private member extension methods.
4 Views