So you can get a "reference" to the same data where one reference gives you the data immutably while the other one lets you change it. Sounds like a recipe for subtle bugs.
What do you mean, it's not like that at all. You only get back the same object (same reference) if it detects the object was immutable to begin with.
I don’t expect higher kinded types any time soon, though.
[1]: http://openjdk.java.net/jeps/325 [2]: http://openjdk.java.net/jeps/305 [3]: http://openjdk.java.net/jeps/309
Personally I rather not be in the bleeding edge and not having to deal with interop issues, or missing tooling.
Also in 2018 interop issues or missing tooling problems are long gone.
Only Scala shops can make effective use of them, and I am yet to do a project where Scala libraries were even considered.
Also, Scala compiler slowness is virtually not a problem any more since introduction of Zinc 1.0. During development, I get repeatedly compile times around 2-5 seconds on Scala 2.11, and recent Scala 2.12.x / 2.13.x showed to be typically 30%-100% faster than 2.11.x.
print(fetch("https://winterbe.com"))
is still this behemoth:
var request = HttpRequest.newBuilder() .uri(URI.create("https://winterbe.com")) .GET() .build(); var client = HttpClient.newHttpClient(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); !?
One can argue about taste, but how can anyone defend such uuuuuuuuurgh?
print and fetch methods and both of those would be equivalent.
The verbosity in that code is less of the typical (and deserved) Java criticism of over-architected pattern cancer. Instead, almost all of the verbosity there is due to a refusal of the language to assume common defaults.
Whether assuming common defaults or forcing people to think about that stuff is good or bad is debatable. But it's certainly far from deserving of the "uuuuuuuuurgh" of a lot of (mostly older) Java I've had to wade through.
You should never try to learn 3D graphics programming if that basic stuff is already "uuuuuuuuurgh" for you.
Why would you need a Builder method on a static object to create a request object? Oh well, let me rephrase that: First you instantiate a Builder object that you need to call the create method on to get a request. Makes no sense to me.
What not make HttpRequest a concrete class and just instantiate it? If there's any good reason for that design please enlighten me.
A builder is a convenient way to wrap up those common settings so that they can be handed to other parts of the code that don't care about them/want to override specific parts and leave the rest in common.
Now, there are other ways to do that (instantiating a concrete class with common settings and mutable fields for customizations in a function, and then passing references to that function to everything that wants the common-config-defaulted output object). The choice between that kind of strategy (or an instantiate-and-freeze-early and pass your mutators in, or a refactor-all-your-code-to-not-mutate strategy etc...) and a builder pattern is a subjective and debatable one. But the approach taken here is certainly defensible.