Readit News logoReadit News
haspok · 2 years ago
> No annotations are required.

I appreciate the intent, but man is this like a minefield waiting to be walked over. Anyone who looks at the code will scratch their head and will not understand what is going on. An annotation would perhaps make it clearer.

Also, how about IDE support? I would argue it is at least as important as the feature itself.

hardware2win · 2 years ago
In C# world they somehow manage to do it without all of this annotation oriented programming
rogerkeays · 2 years ago
Just to make it clear, Fluent does not use any annotations.
michaelcampbell · 2 years ago
Isn't this just saying some languages do things others do not?
stanac · 2 years ago
Not really. First argument (the object you are extending) needs to be marked with `this`, which is an annotation.

Deleted Comment

kitd · 2 years ago
I appreciate the intent, but man is this like a minefield waiting to be walked over. Anyone who looks at the code will scratch their head and will not understand what is going on. An annotation would perhaps make it clearer.

That is the generic argument against extension methods wherever they appear. They are very confusing, until you get used to remembering their existence, then you know what to search for.

Also, how about IDE support? I would argue it is at least as important as the feature itself.

This is mentioned in TFA.

pdpi · 2 years ago
Extension methods in a language that explicitly supports them and with good IDE support are perfectly fine. I love them in Kotlin. Extension methods as a compiler plugin that rewrites the AST... not so great. Great IDE support is a large part of what makes Java worth using, the last thing I need is to break that.
rogerkeays · 2 years ago
Yes, IDE support would help developers find the method that is being called. This is already quite a problem given we have complex class hierarchies and interfaces with default methods. I'm not sure I see the need for an annotation though.
haspok · 2 years ago
A compile-time annotation could at least control whether your plugin is allowed to transform the ADT in the given context (say: for a class). Otherwise is it not possible that it transforms the ADT even when the user did not intend to? Can this be a source of mysterious bugs?
_a_a_a_ · 2 years ago
> is this like a minefield waiting to be walked over

"This looks odd to me so no one else can possibly understand it"is not a rigorous argument.

Both Scala and C# have this. I've used it in my own code to clean things up. It's fine.

skybrian · 2 years ago
Yes, it’s a slightly different language and should have a different extension, like js versus jsx.
erik_seaberg · 2 years ago
Some languages allow declaring things like this per file

  "use strict";

  from __future__ import annotations

  {-# LANGUAGE TemplateHaskell #-}
which probably scales better than 2^n filename patterns.

bilalq · 2 years ago
Looks similar to how you can use implicit classes in Scala[0]. They were definitely convenient for writing unit and integration tests, but difficult to read/maintain. I feel like a pipe operator would be a much more useful alternative instead of syntactic sugar for presenting functions as object method calls.

[0]: https://www.baeldung.com/scala/implicit-classes

sjrd · 2 years ago
Scala 3 has actual `extension` methods, which have a much clearer intent. https://docs.scala-lang.org/scala3/book/ca-extension-methods...
rogerkeays · 2 years ago
Oof... looks more object-oriented hell to me. I really like the way functional programming languages separate types from functions, and I've been adopting this pattern in my Java code. Extension methods let you do this and keep your fluent api. Thanks for the link though, I didn't know about implicit classes.
twic · 2 years ago
We did Scala at an old job and various kinds of implicits got us into so much trouble. I think if you use them judiciously, they'll be fine, but you need quite a bit of experience and maturity to use them judiciously, which most of us lacked.
vips7L · 2 years ago
Scala 3 has actual extension methods.

    extension (c: Circle)
      def circumference: Double = c.radius * math.Pi * 2

    val c = Circle(2, 3, 5)
    c.circumference()

jillesvangurp · 2 years ago
Nice, this is one of the features that makes using Kotlin with existing Java frameworks so nice. It can really cut down on the boiler plate Java is infamous for. You can define extension functions on any type, or type alias. So anything that looks like it could be shorter or is a bit repetitive, you just define an extension function to make that go away.
misja111 · 2 years ago
How does this cut down on boilerplate? The examples given on the website seem equally long.

assertNotEmpty(getHttpContent(createSharedUrl(website, "styles.css")));

vs

website.createSharedUrl("styles.css").getHttpContent().assertNotEmpty();

tuyiown · 2 years ago
Typically, boiler plate implemented by a standalone function is not easily discoverable, eg. no clear convention where to put it, does not look idiomatic on some usages syntax habits, and not suggested by auto completion in top results.

Extensions are searchable by syntax and naturally in a namespace, largely diminishing the risk of put it in in a single use function that will be quickly forgotten, and might seem obscure.

The code itself might not be much shorter, but you don't introduce code looking weird, if it's re-usable it's now discoverable, and if your boilerplate contained a lot of micro adjustments on a larger glue code, this glue code is now shorter and way clearer.

jillesvangurp · 2 years ago
By extracting repetitive bits of code and reducing them to a simple function call.

The website examples aren't very inspiring indeed. Have a look at some of the extension functions for the Collections interface:

https://github.com/JetBrains/kotlin/blob/master/libraries/st...

MrBuddyCasino · 2 years ago
When you start transforming the AST, that might be a sign you should switch languages. Kotlin is nice, why not use it.
kaba0 · 2 years ago
I think Kotlin differs far too much from Java — I don’t want all those plus features that will inevitably branch too far from the JVM/Java corresponding code, becoming its new thing.

I might want a nearly-Java language that only adds trivial syntax sugar, but are otherwise the same. Groovy sort of had a good initial idea here (being a superset of Java, though again, it has grown apart a bit since).

For me Kotlin lives in this weird limbo between these two extremes. If I want a different language on the JVM I would rather do Scala or Clojure.

rogerkeays · 2 years ago
Kotlin is great, but it is a fairly heavy dependency if all you want is extension methods. Java has mostly caught up in many other aspects, so I'm experimenting with Java + one or two compiler hacks. Checked exceptions are my next target...
grashalm · 2 years ago
Another java fork like Lombok. But this time the authors didn't take the time to support all java compilers/IDEs, so the situation is even worse.

If this is just to highlight the merit of static extension methods with a follow up JEP I am all for it, but please don't advertise this as a feature for production. It's a trap.

rogerkeays · 2 years ago
Do you really think a JEP is worth investing my time in? AFAICT, the Java gods have already made up their minds on extension methods.
grashalm · 2 years ago
I did some digging on past discussions, and yes, it seems the stars are not aligned for extension methods in standard Java.

But tbh, there are some very good arguments against extension methods. Also, some tricky questions about overloading handling and compatibility are lurking in the shadow. But if you have good suggestions on how to fix them, I'd take the time to propose something on an OpenJDK mailing list, maybe you get some support.

3cats-in-a-coat · 2 years ago
Lombok is not a Java fork.
grashalm · 2 years ago
Well a language fork. But not a full implementation fork of course. Or would you argue that what Lombok does is part of the java spec? It effectively extends the java spec in non backwards compatible ways.
kitd · 2 years ago
Known Issues

Fluent will make you a more productive programmer, which may go against corporate policy.

Ha!

Anyway, nice work. Similar to D's uniform function call syntax.

https://tour.dlang.org/tour/en/gems/uniform-function-call-sy...

There's some more use cases in that link too.

rogerkeays · 2 years ago
This! It even has a fancy name to satisfy the purists.
sorokod · 2 years ago
For me, any functionality that requires a compiler plugin, automatically raises the bar for adopting that functionality. Any extra features have to be contrasted with essentially modifying the language.
jitl · 2 years ago
I would only use this if I couldn’t use Kotlin, which has excellent extension method ergonomics that compile to basically the same thing as this.
sacnoradhq · 2 years ago
Yep. It will be a footgun for environments with and without JAVAOPTs.

Better off transforming .java code at compile-time into .class'es in a .jar that always works at runtime.

rogerkeays · 2 years ago
Fluent transforms the abstract syntax tree at compile-time resulting in .class'es in a .jar that always work at runtime. There are no runtime dependencies.
exabrial · 2 years ago
This is "cool", and really demonstrates the extensibility of the language, but definitely a nuclear minefield and something I would never use for anything other than a demonstration.

This really isn't solving any real problems either. The first set of syntax shows definitive programmer intent at the cost of.... 4 extra keyboard presses. The code will also fail compilation or even at runtime if some API changes in a dependency, which is a _good thing_.

mdasen · 2 years ago
I feel like this misses the reason I like extension methods: discoverability.

With an extension method, I can do `object.` and my IDE will tell me what can be called on object. With a static helper method, it isn't as easy to know what is available. I need to know which helpers actually exist.

Since this doesn't have IDE support, it doesn't help discoverability. I'm not going to get nice autocomplete that shows me what is available. In fact, my IDE is going to highlight it as a bug. If I have a spelling mistake, I won't be able to easily pick it up - I'll assume it's just the normal complaint for all of these fluent extension methods.

That makes this simply syntactic sugar rather than something that actually helps me discover things more easily. It then hurts readability and navigation since I can't easily click through to get the definition of the method.

On a more general note about Java, things like this are one of the reasons I don't love the Java ecosystem. People try to change the behavior of Java in really hacky ways that don't work well. I understand that it's an attempt to overcome shortcomings in the language, but when one looks other languages it becomes clear that Java could have just evolved the language to be better. Java has lots of good things and I'm not looking to argue that. However, when I look at things like this, it makes me think that Java needs to really address the core language.

Instead, we get lots of tools like this which might be nice, but make it really hard to understand what's going on. Electronic Arts created an async/await library that'll do crazy stuff to let you do async/await style programming (https://github.com/electronicarts/ea-async). Yes, Java is doing good things with structured concurrency and Project Loom, but the point is how people keep trying to work around the language. There are so many POJO generators it isn't funny: AutoValue, Immutables, JodaBeans, Lombok, and more I'm probably forgetting. Java records don't fulfill everything (and they're at least a decade late). Java doesn't support expression trees for lambdas so libraries sometimes do crazy hacky things to make that exist.

Java is a great piece of technology, but it feels like people are often trying to overcome issues with the language through really hacky means in a way that I don't see in other languages. Java is getting better about modernizing the language, but it still feels like people are running against the language more than in other ecosystems.

za3faran · 2 years ago
Can you elaborate on what you mean by expression trees for lambdas?