<div dir="ltr">> if someone from API designers, who once rejected this proposal, would spare some time to discuss this topic with me.<br><br>I am not that - you'll find I have no particular influence - but while I'm here.<br><br>* This is a very commonly requested feature, they are aware of the desire for it.<br>* A change like this would probably live under the banner of the amber project (feel free to forward the thread to amber-dev for a higher chance at a response, maybe)<br>* There are more ways to address the tension than extension methods<div><br>To elaborate on that last point, consider this program<br><br><font face="monospace">import org.apache.commons.lang3.StringUtils;<br><br>import java.util.Locale;<br><br>void main(String[] args) {<br>    String speech = """<br>            Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal.<br>            """;<br><br>    String drunkFriendSpeech = StringUtils.abbreviate(<br>            speech.toUpperCase(Locale.US),<br>            20<br>    ).replace("OUR", "OUR (*burp*)");<br><br>    System.out.println(drunkFriendSpeech);<br>}<br></font><br><font face="monospace">$ </font>FOUR (*burp*) SCORE AND SE...<br><br></div><div>What extension methods are syntax sugar for is making logic like <span style="font-family:monospace">org.apache.commons.lang3.StringUtils#abbreviate</span><font face="arial, sans-serif"> appear in code as if it were an instance method.<br><br></font><font face="monospace">    String drunkFriendSpeech = speech.toUpperCase(Locale.US)<br>            .abbreviate(20)<br>            .replace("OUR", "OUR (*burp*)");</font><br><font face="arial, sans-serif"><br>But the downsides are what has been pointed out.<br><br>* You no longer know if `.abbreviate` is a method call or a call to StringUtils.abbreviate from local analysis.<br>* Whether it is valid code is determined by an import of some kind.<br>* Hey, what if they actually added an abbreviate method to String...would this code change meaning?<br>* ...etc.<br><br>But if there was an alternative syntax for invoking static methods you could resolve the tension that way.<br><br></font><span style="font-family:monospace">    String drunkFriendSpeech = speech.toUpperCase(Locale.US)</span><br style="font-family:monospace"><span style="font-family:monospace">            |> StringUtils.abbreviate(_, 20)</span><br style="font-family:monospace"><span style="font-family:monospace">            .replace("OUR", "OUR (*burp*)");<br></span><font face="arial, sans-serif"><br>Infinite bikesheds notwithstanding, If the amber project ever adds something to address the "Static Methods Ugly to Chain" problem I personally think it will be something in this direction. That would also probably come well after pattern matching and probably also after valhalla, if it comes at all, so I wouldn't hold your breath.<br><br>> </font>Writing code using utility methods instead of extensions is just slower, developers have to waste more time writing a statement than it would be with extension methods.<br><br>What's going to suck to hear, but I think that you'll come around eventually, is that extension methods do not improve code readability. They make it harder to read o<font face="monospace">.method() </font><font face="arial, sans-serif">since it would be ambiguous whether </font><font face="monospace">.method</font><font face="arial, sans-serif"> is an instance method or an extension method.*<br><br>They *do* make it easier to write programs though. Without them you do have to write more characters and you do sometimes have to break up method chains.<br><br>Historically, given a choice between code readability and code writability/terseness, Java has erred towards the first.<br><br>* Technically it's already ambiguous, but calling static methods through an instance variable is uncommon so we don't do a double take on it. Extension methods would be used commonly enough that you would have to think about it.</font></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Apr 23, 2024 at 3:35 AM ІП-24 Олександр Ротань <<a href="mailto:rotan.olexandr@gmail.com">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="ltr">Well that's just really frustrating for me.<div><br></div><div>I am pretty sure the point I will provide as advantages has already been brought up here numerous times, but I will take some time and would appreciate it if someone from API designers, who once rejected this proposal, would spare some time to discuss this topic with me.</div><div><br></div><div>1. "Poor reflective discoverability" essentially means extension methods are not accessible when inspecting class members. That is not some inherent issue of this feature, this is just the way it should be. I'm not really sure if there is someone who has ever been hurt by this, besides maybe some parser-based solutions, but let's be honest, this is a: solvable, b: ridiculously exotic to consider.</div><div><br></div><div>2. Documentation accessibility is a strange point for me to be fair. Every IDE nowadays is capable of fetching the right documentation, as well as explicitly mentioning where the method comes from, as it is done in C#, kotlin, swift and many other languages. I don't think anyone has ever heard complaints about poor documentation of LinQ. Unless someone is writing in notepad, this is poorly applicable.</div><div><br></div><div>3. Not overridable. Should they be? I don't think there is a way to achieve some kind of "polymorphic" extensions, and I don't think there should be: extension methods should provide polymorphic target handling, floow LSP etc., not the other way around.</div><div><br></div><div>4. C# extension methods indeed have some very serious drawbacks compared to Java's, but doesn't this also go the other way around? Canonical utility functions breach object-oriented code-style, making users write procedural code like Utils.doSome(obj, params) instead of obj.doSome(params). Its common issue users just aren't aware of the existence of certain utility classes and end up with nonoptimal code. </div><div>Code without extension methods is always much more verbose, if the API is supposed to be fluent developer could end up with deep nested invocations. This brings numerous problems, such as majorly reduced readability, as the utility methods wrap each other and the developer reads the processing pipeline "from the end". Also reduced readability always means increased change of errors.</div><div>Writing code using utility methods instead of extensions is just slower, developers have to waste more time writing a statement than it would be with extension methods.</div><div>Some other advantages I will list below, after this list is ended.</div><div><br></div><div>5. One of the answers from the first thread you provided (<a href="https://stackoverflow.com/a/29494337" target="_blank">https://stackoverflow.com/a/29494337</a>) 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. 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.</div><div><br></div><div>Now moving on to some of my personal points. I am also developing some core libs APIs, and sometimes extension methods are just craving to be used. Modifying widely-used interfaces is always painful, but that's the only way to provide a concise way to communicate with existing APIs. Moreover, Java is an old language and some internal implementations of APIs, like Stream implementations, are so juncted that adding something new to these classes directly becomes a spec-ops task. Some APIs, like Gatherer API or Collector API, arise just from this simple necessity to introduce new behaviour without modifying extended class itself.</div><div><br></div><div>Extension methods are de-facto standard for modern languages: C#, Kotlin, Swift, Rust and any other modern language provide this option. JS also has its own unique way of extending APIs. The only modern widely-used language that does not have extension methods is Python, but that only applies to built-ins, custom classes could be extended as well. When Java refuses to introduce this feature, I suffer major damage in the eyes of potential switchers from ANY other language available right now, which is retrograde and, as for me and any other supporter of Java, really upsetting.</div><div><br></div><div>Introduction of extension will not invalidate previously written code: if one wants, they can still use utilities as earlier and pretend that nothing happened. However, for other, significant, if not to say major, part of the community, this would be a valuable addition..Virtually every Java utility library: lombok, manifold, xtend - provide extension method functionality, which clearly shows there is a demand for a feature. </div><div><br></div><div>The extension methods are just syntax sugar, nothing more. They provide better developer experience, make code less verbose and more readable, which reduces chance of errors and helps to develop apps faster, while not affecting performance in any way, which is crucial in today's world and may be a major concurrent advantage.</div><div><br></div><div>Also, last but not least, noone from Java developers teams will have to put efforts into implementation. I am willing to take one full feature development lifecycle, from drafts to testing and integration. Of course, final changes will need to be reviewed, but I don't think this will be an unbearable burden. Regarding implementation, these changes are really non-invasive, and are really unlikely to introduce any issues, it already passes all existing tests.</div><div><br></div><div>I sincerely hope this letter will bring up this discussion once again, as I am open for dialogue, but I am standing my ground about numerous advantages this feature has. If that's possible, I may file a draft JEP and let the community vote for or against it, to see what Java users think about this proposal.</div><div><br></div><div>Best regards,</div><div>Hoping to receive some feedback</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">вт, 23 апр. 2024 г. в 07:01, Ethan McCue <<a href="mailto:ethan@mccue.dev" target="_blank">ethan@mccue.dev</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="ltr">This subject has been addressed publicly by the language team at various points. These are just a few I found, I'm sure there is more elaboration out there. <br><br>Implementation choices aside, the API of "add a static method and mark it as an "extension method", call like instance method" seems to have been rejected.<br><br>> C# extension methods have some very serious drawbacks compared to Java's default methods (for example, poor reflective discoverability, poor discoverability through documentation, not overrideable, require ad-hoc conflict-management rules)<br><br><a href="https://stackoverflow.com/questions/29466427/what-was-the-design-consideration-of-not-allowing-use-site-injection-of-extensio" target="_blank">https://stackoverflow.com/questions/29466427/what-was-the-design-consideration-of-not-allowing-use-site-injection-of-extensio</a><br><br>> What I believe you are hoping for is the ability to "monkey-patch" a method into a class you do not control, but Java does not give you that (by design; it was considered and rejected.)<br><br><a href="https://stackoverflow.com/questions/24096421/java-8-add-extension-default-method-to-class" target="_blank">https://stackoverflow.com/questions/24096421/java-8-add-extension-default-method-to-class</a><br><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Apr 22, 2024 at 7:24 PM ІП-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="ltr">Subject: Proposal for Introducing Extension Methods to Java<br><br>Dear Java Development Team,<br><br>I hope this email finds you all in good spirits. I am writing to propose the integration of extension methods into the Java programming language, a feature that I believe holds considerable promise in enhancing code readability and maintainability.<br><br>Extension methods offer a means to extend the functionality of existing classes in a manner that aligns with Java's principles of static typing and object-oriented design. The proposed syntax, exemplified as follows:<br><br>public static void extensionMethod(extends String s) { ... }<br><br>adheres to established conventions while providing a concise and intuitive means of extending class behavior. Notably, the use of the `extends` keyword preceding the type parameter clearly denotes the class to be extended, while the method itself is declared as a static member of a class.<br><br>I wish to emphasize several advantages of extension methods over traditional utility functions. Firstly, extension methods offer a more cohesive approach to code organization by associating functionality directly with the class it extends. This promotes code clarity and reduces cognitive overhead for developers, particularly when working with complex codebases.<br><br>Secondly, extension methods enhance code discoverability and usability by integrating seamlessly into the class they extend. This integration allows developers to leverage IDE features such as auto-completion and documentation tooltips, thereby facilitating more efficient code exploration and utilization.<br><br>Lastly, extension methods promote code reusability without the need for subclassing or inheritance, thereby mitigating the risks associated with tight coupling and inheritance hierarchies. This modularity encourages a more flexible and adaptable codebase, conducive to long-term maintainability and scalability.<br><br>In light of these benefits, I believe that the integration of extension methods into Java would represent a significant step forward for the language, aligning it more closely with modern programming paradigms while retaining its core strengths.<br><br>I am eager to discuss this proposal further and collaborate with you all on its implementation. Your insights and feedback would be invaluable in shaping the future direction of Java development.<br><br>Thank you for considering this proposal. I look forward to our discussion.<br><br>The draft implementation can be found in the following branch of the repository: <a href="https://github.com/Evemose/jdk/tree/extension-methods" target="_blank">https://github.com/Evemose/jdk/tree/extension-methods</a>. I am new to Java compiler development, so any tips or remarks about what I have done in the wrong way or in the wrong place. I will add complete test coverage a bit later, but for now, there is "jdk" archive in the root directory of repo, which contains built in jdk for windows x86-64. If someone is willing to participate in testing as user, I would appreciate any help.<br><br>Best regards<br><div><br></div><div>PS: Note about internal implementation: it introduces a new flag - EXTENSION, that is equal to 1L<<32. It seems like it takes the last vacant bit in a long value type that has not been taken by flags. Not sure what the compiler development community should do about this, but it feels like it could be an obstacle to new features that might be introduced later.</div></div>
</blockquote></div>
</blockquote></div></div>
</blockquote></div>