<div dir="ltr"><div>In my mind, the main motivation of extension methods is to rearrange the syntax tree, replacing nesting calls with chaining, prefix with postfix.</div><div>I.e., replacing:</div><div><span style="font-family:monospace">f1(f2(f3(x, "p3"), "p2", "p22"), "p1")</span></div><div>with</div><div><span style="font-family:monospace">x.f3("p3").f2("p2", "p22").f1("p1")</span><br></div><div>It significantly untangles the code and makes it more readable. Good example of good usage for it, could be the java-streams api, to add user defined stream operations.</div><div><br></div><div>as for "the illusion of belonging" it could be addressed by introducing some special operator instead of dot to highlight the difference, e.g. something like:</div><div><span style="font-family:monospace">x¬f3("p3")¬f2("p2", "p22")¬f1("p1")</span></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 24 Apr 2024 at 20:07, Brian Goetz <<a href="mailto:brian.goetz@oracle.com" target="_blank">brian.goetz@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
<div>
<br>
<div>
<blockquote type="cite"><span style="float:none;display:inline">5. One of the answers from the first thread you provided (</span><a href="https://stackoverflow.com/a/29494337" target="_blank">https://stackoverflow.com/a/29494337</a><span style="float:none;display:inline">)
states that omitting extension methods is a "philosophical choice", as API developers should define the API. I have to strongly disagree with that. Extension methods are NOT part of the API, they are EXTENSION to it. It does not breach encapsulation as it
can't access any internal members of API classes. </span></blockquote>
<div><br>
</div>
<div>You can convince yourself that you like it, but that doesn’t change the fact that it is a deliberate attempt to blur the boundary of the API. And again, you might think that is fine, but we do not. The members of String, and therefore the methods
you can invoke through a String receiver, should be defined by the String class (and its supertypes.). Invoking a method on a receiver:</div>
<div><br>
</div>
<div> aString.encrypt()</div>
<div><br>
</div>
<div>where String has no method called encrypt(), is muddying the user’s view of what the API of String is. I get that you are willing to say “the API of String is the methods in String, plus any methods I care to create the illusion of belonging
to String”, but that looks like monkey-patching to us. Worse, this “method call” might mean one thing in one context, and another thing in another context. </div>
<br>
<blockquote type="cite"><span style="float:none;display:inline">Extensions have to be imported explicitly (not the containing class), so they are explicitly mentioned in the imports list. Also, are utility methods also breaching
this rule then? The only real difference I see is differences in notation, and extension methods are clearly much more concise.</span></blockquote>
</div>
<br>
<div>Concision is not the goal of programming.</div>
<div><br>
</div>
<div><br>
</div>
</div>
</div>
</blockquote></div><br clear="all"><br><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature">WBR, Anatoly.</div>