<div dir="ltr">I have tried writing some code and utilizing extension methods as much as possible in a production-like application to explore pros and cons of them in depth. Here I would like to share my experience along with some ideas that I came up with based on it.<div><br></div><div>One thing I have to admit, is that they turned out much less usable then it seemed to be for me. In fact, I found a major blind spot that could be covered by their common design in most languages: they are virtually incompatible with DI containers due to their static nature.</div><div><br></div><div>Essentially what my project is doing is taking an equation and parses it into polynomial form and then solves it. I was trying to separate equation validation logic from actual parsing as both of them are really complex using JSR 303 Bean Validation API. Well, as you might expect, there was no way to make this work together, because static methods cant be validated. After some thinking I figured that besides bean validation, static methods are also incompatible with runtime-weaved AOP, which is widely used in industry (annotations like @Transactional, @Cachable, @Async etc. (names are listed for Spring framework, but I'm sure there are things like that in Jakarta EE and other frameworks too)). For example, if one tries to implement something like Active Record using extension methods, transaction or async support provided by the framework is just unavailable.</div><div><br></div><div>That led me to some ideas about extensions by members of class (this was kind of inspired by how delegation in kotlin works). I haven't thought about syntax, but it could be something like "private StringUtils utils = ... extends String".</div><div>This solves a few problems:</div><div>1. Extensions become overridable</div><div>2. Extensions specified explicitly, however, still doest completely fix issue with blurring edges between API and extension.</div><div>3. This instance-based extension enables integration with DI containers which is a base of modern frameworks.</div><div><br></div><div>However, there is also a cons coming with this approach like the fact that many utility classes aren't meant to be instantiated and their constructors might be not available. This is bypassable, but clearly not desired.</div><div><br></div><div>I want to make things clear that I am NOT proposing this API because this is just some half-expromt conceptions and in a very raw state. However, I haven't heard this suggestion anywhere so I thought this idea is worth sharing with the community.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">ÑÑ€, 24 апр. 2024 г. в 23:56, ІП-24 ОлекÑандр Ротань <<a href="mailto:rotan.olexandr@gmail.com">rotan.olexandr@gmail.com</a>>:<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 dir="auto">Sorry for duplicate, Gmail for some reason decided to exclude amber-dev from recipients initially</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Apr 24, 2024, 23:55 ІП-24 ОлекÑандр Ротань <<a href="mailto:rotan.olexandr@gmail.com" target="_blank">rotan.olexandr@gmail.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 dir="auto"><div dir="auto"><span style="font-size:12.8px">Actually, that what I have thought about. This is a good way to find compromise, I thought about syntax like obj>ext(), which implies object is "injecting" into utility method. However, this introduces a new syntax, and as I reckon, Java is going for the most simple syntax possible, and this might still clash with it.</span><div dir="auto" style="font-size:12.8px"><br><div dir="auto">Other thing that I have thought of is that some extensions (like previously mentioned LinQ), actually *should* look like an API itself, as they are extension provided by the same team that made an API. There could be some ways to achieve this like allowing dot syntax for extensions from same module and arrow from any outer, so there are something like trusted and untrusted extensions, but this adds new concepts to language, which is also udesirable.</div><div dir="auto"><br></div><div dir="auto">Although, I am glad to see that this idea is still not discarded completely. I agree that the place where extensions are the most needed is fluent apis like streams, that could contain many operations in chain, and nesting makes code barely readable. As I understand, readability is what Java going for, so with some adjustments, such feature could enhance readability in some cases while not damaging it in another. The syntax Anatoly proposed could be a point where there are virtually aren't any major cons, while preserving all the pros.</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Apr 24, 2024, 23:32 ІП-24 ОлекÑандр Ротань <<a href="mailto:rotan.olexandr@gmail.com" rel="noreferrer noreferrer noreferrer" target="_blank">rotan.olexandr@gmail.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 dir="auto">Actually, that what I have thought about. This is a good way to find compromise, I thought about syntax like obj>ext(), which implies object is "injecting" into utility method. However, this introduces a new syntax, and as I reckon, Java is going for the most simple syntax possible, and this might still clash with it.<div dir="auto"><br><div dir="auto">Other thing that I have thought of is that some extensions (like previously mentioned LinQ), actually *should* look like an API itself, as they are extension provided by the same team that made an API. There could be some ways to achieve this like allowing dot syntax for extensions from same module and arrow from any outer, so there are something like trusted and untrusted extensions, but this adds new concepts to language, which is also udesirable.</div><div dir="auto"><br></div><div dir="auto">Although, I am glad to see that this idea is still not discarded completely. I agree that the place where extensions are the most needed is fluent apis like streams, that could contain many operations in chain, and nesting makes code barely readable. As I understand, readability is what Java going for, so with some adjustments, such feature could enhance readability in some cases while not damaging it in another. The syntax Anatoly proposed could be a point where there are virtually aren't any major cons, while preserving all the pros.</div><div dir="auto"><br></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Apr 24, 2024, 23:23 Anatoly Kupriyanov <<a href="mailto:kan.izh@gmail.com" rel="noreferrer noreferrer noreferrer noreferrer noreferrer" target="_blank">kan.izh@gmail.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 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" rel="noreferrer noreferrer noreferrer noreferrer noreferrer noreferrer" 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" rel="noreferrer noreferrer noreferrer noreferrer noreferrer noreferrer" 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>
</blockquote></div>
</blockquote></div></div>
</blockquote></div>
</blockquote></div>