Why There Is Interface Pollution in Java 8
blog.informatech.cr
blog.informatech.cr
interface IOConsumer<T> extends Consumer<T> {
@Override
default void accept(T t) {
try {
maybeAccept(t);
} catch (IOException ie) {
throw new RuntimeException(ie); }
}
void maybeAccept(T t) throws IOException;
}
As IOConsumer<T> is also a Consumer<T>, if you can assign the lambda to an IOConsumer<T> it will get this wrapping behaviour automatically. So your code might look something like: try (Writer writer = new StringWriter()) {
final IOConsumer<String> ioPrinter = writer::write;
// hand ioPrinter off to something that expects a Consumer<String>
}
This is by no means beautiful; for 'writer::write' to be treated as an IOConsumer<T> requires that the target type be IOConsumer<T>, so typically would require an interim assignment. It does allow us to simplify the 'wrapping' method, though, so that lambdas can again be used as one-liners: static <T> Consumer<T> maybe(IOConsumer<T> consumer) {
return consumer;
}
try (Writer writer = new StringWriter()) {
final Consumer<String> printer = maybe(writer::write);
}
It would be nice not to have these wrinkles, but I think Java 8 has done a fairly decent job of preserving backwards compatibility while introducing language features and APIs which feel like a vast improvement. I'd love to see reified generics in the future, particularly if the type parameter can be extended to support primitives. interface ConsumerE<T, E extends Exception> {
void accept(T t) throws E;
}
This actually works! The type inference is good enough to figure out the actual type of E.Note that Java 8 also includes specialized wrappers like RuntimeIOException. So it might be nice to extend your example:
static <T, E extends Exception> Consumer<T> wrapped(
Function<? super E, RuntimeException> wrapper,
ConsumerE<T, E> consumer) {
return (t) -> {
try {
consumer.accept(t);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw wrapper.apply((E) e);
}
};
}
Used as follows: Consumer<String> printer = wrapped(RuntimeIOException::new, writer::write);> but for such a large code-base I think building dependencies from source ... is probably not a bad idea.
That's a bad idea. You want to manage as little code as possible, especially given the already large codebase. It's certainly doable, but in the end you realize the benefit is just not worth the effort.
Of course, that was just a symptom of a far larger problem: It always seemed that when faced with the dilemma of favoring some PL research goal vs. real working-man's use, Scala always chose the former; it was like its real (though not stated) target audience were PL PhDs. It seems the winds have shifted recently, but probably too late, and Scala is already weighed down by too many "PhD" features that need to be removed in a way that would severely break source compatibility.
Say what you want about Java, it's really great for big projects you must depend on and need to maintain for many years.
The benefit of using a language that, at _worst_, is as productive as Java, and at best miles better?
>faced with the dilemma of favoring some PL research goal vs. real working-man's use, Scala always chose the first
Scala is pretty straightforward in terms of features, classifying it as "PL research" is a bit much.
>Say what you want about Java, it's really great for big projects you must depend on and need to maintain for many years.
My experience has been that larger projects end up accumulating so much boilerplate that it becomes extremely hard to manage (I fear that Scala's standard library is becoming like this too, but third-party libs seem to avoid this).
I have trouble finding any non-deployment-related argument against Scala in the Scala vs. Java comparison.
I completely disagree with this. If "productive" means fewer lines of code -- then yes. But for a large-scale project, productive usually means code that another developer can understand quickly, and by that metric I think Scala loses big-time.
> I have trouble finding any non-deployment-related argument against Scala in the Scala vs. Java comparison.
Then either you haven't had enough experience with Scala (not on your own, but in a large team[1]) or you haven't looked. I and many others can list plenty, but I've said much of that before, and you can find a lot of other people's experiences online. In the end, it all comes down to tradeoffs, and you can find many valid arguments for both preferences.
[1]: It can be argued that almost no one had (and neither have I) because Scala hasn't been around long enough, but overseeing development of (non-Scala) software that needs to last for at least a decade, as well as the later evolution of similar projects, it quickly became clear (to me, at least) that Scala isn't a great fit for such projects (at least not for many developers). People had a harder time understanding Scala code that was written by another team member a week earlier than Java code written 7 years earlier. While you certainly can be too clever in Java if you put in enough effort, it's waaay to easy in Scala. You can immediately see how the programmer became too bored of the actual problem they had to solve and decided to amuse themselves by playing with the language. This is something I've seen happen in C++ projects too, but to a lesser extent. I can guess that part of the reason is that when almost everyone was using C++, the internet, and certainly blogs, weren't so widespread and influential, so the really clever tricks couldn't spread so quickly. Also, when C++'s harm became apparent, discipline was quickly enforces in many organizations, and it was much easier to enforce discipline over C++ developers back then, than over Scala developers today, because many of those are cowboys to begin with. Still, maintaining long-lived C projects is easier than maintaining C++ projects, so much so that many wish they had chosen C over C++ when they first began development.
False.
Results 1 - 10 of 119,620
What's your point again?I also understand that you think it would be a wise decision on the part of Bank of America to write their software in Scala, or Raytheon to choose Scala for their aircraft carrier's C3I system; maybe you believe that a more expressive type system will lead to fewer bugs in such large systems, or that fewer lines of code offset its cleverness. You might think that the extreme lengths taken to ensure you never have to cast a type during collection transformations isn't PL-research showmanship that comes at the expense of code readability and getting stuff done, but a wise bug-preventing measure. But you should realize that people criticize your favorite language(s) for valid reasons. Maybe they have different constraints from yours, and maybe they favor other tradeoffs. Especially given that Scala -- unlike Java, Swift or Go -- was never meant to be "a language for everyone" (and neither is Clojure), it should come as no surprise that not everyone likes it, and for good reasons. Why, those reasons were deliberate! What I find annoying is trying to disown those decisions, deny those tradeoffs, and pretend Scala was a language designed not by professors and PhD students but by industry veterans. Both are, of course, excellent candidates for language design (look at Erlang and Haskell), but each group would choose different tradeoffs, and the languages they produce reflect that. Personally, I think "PL research" languages pave the path to the future and influence "industry" languages, but are often the wrong choice for serious industry projects. Going back to Erlang and Haskell, they're an interesting example because both try to solve kind of the same issues, and they're both superb languages; still, if the CTO of an airport asked me which language to use for their next critical system, I wouldn't hesitate before recommending Erlang and warning -- quite strongly, in fact -- against choosing Haskell.
That's a very unequivocal conclusion but you didn't say anything about the reason for such a decision. Could you say a few words about that?
btw, these libraries are developed by industry veterans & all of them have commercial support. For success stories go here: https://typesafe.com/company/casestudies
Well, it would be silly to make such a broad, and hypothetical generalization, but as far as the "academic" languages I've seen, let's say a lot of caution is required before adoption in the industry. See my answer to tome.
> If you look at the top libraries/frameworks that are build on top of Scala...
While I can dispute your claim about most of the libraries you've mentioned, I can wholeheartedly agree that some Scala libraries provide much prettier APIs than Java libraries can. Still, the same can be said about C++ APIs vs. C APIs, and in spite of their elegance, a lot of large projects wish they had stuck with uglier C APIs, because most benefits come with costs attached. I'm not saying that Scala doesn't have any benefits -- it's got plenty. I'm just saying that in the case of Scala, its costs far outweigh its benefits.
The interesting question to me is, can we extract some of the goodness Scala brings without paying so dearly for it? The question is yet to be answered satisfactorily, but I think languages like Kotlin (or Swift, which, from what I've seen, looks very similar to Kotlin) show that this might indeed be possible.
This is a complete caricature of the benefits of type-safe languages. Why should anyone engage with you when you can't be bothered to look into the (claimed) benefits of what you're arguing against?
1. If you could manage to make a single point without
using multiple strawmen and sweeping generalizations,
people would take you more seriously.
2. Just read your own text. You have made up your mind
(perfectly fine), but you are desperately making up
arbitrary claims to fit your own view (increasingly
ridiculous).
3. Additionally, you are completely unable to refer to
specific instances of what you think is wrong and only
respond with abstract platitudes which could include
everything or nothing.
4. Reading a bit about Scala on the Internet and
repeating it doesn't make you an expert.
That's the issue.Also, your insistence that Scala isn't a research language is based on... I don't know what. Unlike, say, Clojure or Erlang, that tried to solve specific software engineering pain points (state management, fault tolerance), Scala started as a research language designed to test a PL hypothesis: how well can FP and OOP mesh, and will doing so be helpful. It also experimented with advanced type systems, and recently with statically typed language. None of the motivations behind these features was an industry problem. No one in the industry said, "you know what, type safe macros is what's going to make our automation control software easier to maintain". Their motivation came from conjectures compiler writers had about novel language features and how they might be used when writing a piece of code. You can deny this all you want, but those are facts. What is opinion is the analysis of the result: I claim that the result is a kitchen-sink language with too many features -- most of them marginally useful when building the next stock-market exchange -- and all of them contribute complexity whose cost far exceeds its benefit, resulting in a language whose net contribution to industry projects (not research projects) is negative. Feel free to disagree. If you think valid claims only pertain to the discussion of the for comprehension syntax, then you should try managing large projects and see that it's the philosophy of the language and combination of features that matters.
You keep making huge claims and sweeping generalizations based on a completely irrelevant version of Scala ("a few years ago" == "not a version which would give any useful information to judge Scala today"), without being able to support any of it with even a glimpse of detail.
At the same time, you come up with requirements where there is just no chance to actual fulfill them, e. g. bashing the language for both being not production-ready before 2.8 (is that even a point worth discussing?) and for rapidly improving on exactly these issues (OMG!!! It is changing too fast!).
I think you should really make your mind up on these things, because you can't have it both ways.
I'm saying this because this incoherent reasoning is constantly happening in your comments, it's not some isolated case.
I'm sorry, but you're just not getting it. I don't take issue with Scala's choice of square brackets over angled brackets. I take issue with the language philosophy and combined set of features. Here are the most detailed details: too many features, many of them overlapping (traits, structural types); too much complexity (type system, implicits); less readable; not enough constraints (e.g. immutability not enforced, casts allowed everywhere). That's as detailed as it gets. All in all, it came out benefits << cost. That's it.
Either you don't want to understand or you think that when Boeing wants to write some big aircraft software thingy they say, "hmmm., the type inference is insufficient for our needs", or, "if only we had non-strict evaluation...". Because that's not how it works. In the industry languages are evaluated as a whole based on the project's criteria, with all their combined benefits weighed against their combined costs. This is what we've done. Scala came out lacking: too much overall cost for too little overall benefit. It was too complicated, too unconstraining, too unreadable, and too difficult to upgrade and build. What more do you want?
> "not a version which would give any useful information to judge Scala today"
No, I'm sorry, but you're just plain wrong! I gave up on Scala some years ago, but I can still tell its evolution has been in the opposite direction from what we wanted. Since then the language has become even bigger, more complex, more obtuse (collections) and even less constraining (macros). Even if the build and upgrade issues are better, the PL research philosophy is still there and its effects are only worse than they were some years ago.
Bashing the competition with FUD is never acceptable for me.
Sometimes I wonder how many accounts that pron guy actually has.
Accusing one person of FUD, and then accusing him of sockpuppeting in the same thread, while failing miserably at turing-test level human detection... really, I think this comment does more credibility damage to itself than to anyone it's trying to cast shade upon.
That's like criticizing Java for the lack of Generics by picking Java 1.4 as a reference.
It looks like the recent version upgrades for finagle and twitter-util were pretty smooth, so what's the point of picking old data over new?
The Scala team has further caused optic issues here by using what appears to be a semantic version number but in no way shape or form following semantic versioning procedures around compatibility breaking changes.
[edit] Further bringing Java 1.4 into this is really problematic as it is past the 10 year mark on age and will run just fine with nearly any Java project right now.
Then enterprises should probably stay away from Java, too.
Java 7 GA: July 2011.
Java 7 EOL: April 2015.
That's not even 4 years.> The Scala team has further caused optic issues here by using what appears to be a semantic version number but in no way shape or form following semantic versioning procedures around compatibility breaking changes.
Yes, I agree.
I have suggested changing this multiple times, so that the HN peanut gallery isn't intellectually overwhelmed with the epoch.major.minor.patch scheme anymore.
> Further bringing Java 1.4 into this is really problematic as it is past the 10 year mark on age and will run just fine with nearly any Java project right now.
You could also run old Scala code on a current JVM.
_But_ you can also deploy current Scala to a 10 year old JVM, which is not possible with Java.
You are being either extremely confused or employing a pretty smarmy rhetorical tactic by equating what the thread was about, source compatibility, and jvm support lifetimes.
"I have suggested changing this multiple times, so that the HN peanut gallery isn't intellectually overwhelmed with the epoch.major.minor.patch scheme anymore."
Here you further degrade your argument by:
1) debasing the people who are arguing against you, people who have used and are using Scala currently and historically, just because they have issues with your pet language and
2) belittling the actual issue with using a semantic version number without using semantic version scheme. Some of the high level complaints about Scala include that they don't follow industry standards, that they show a lack of industry experience, that there is no idiomatic Scala way for newcomers to adopt. All of those are in evidence with the way they handle compatibility and versioning. It's not a reason in and of itself to give up on the language, but it is a damning problem that many people have run into many times. Scala is getting better at this but they have traditionally been abysmal so that is small comfort.
"You could also run old Scala code on a current JVM. _But_ you can also deploy current Scala to a 10 year old JVM, which is not possible with Java."
Once again you are either intentionally changing the goal posts, or are showing extreme ignorance. We were talking about source compatibility. You can count on 1 hand the number of source compatibility issues you will run into with a 1.4 code base and a modern jdk. Even turning on deprecations will leave you with a very small amount of changes that need to be done. This is an extremely valuable property for some projects. Instead of trying to argue poorly against this benefit with bad rhetorical techniques, why don't you just admit what the rest of us know. Java made compatibility a huge priority. That it is a huge priority causes many many issues with the language. For many projects those issues make other languages more appropriate, but for others it is a huge boon. Scala simply made different trade offs, which make it more appropriate for some projects and less appropriate for others.
I am a Scala developer currently and hope they don't try to emulate the compatibility model of the Java world because the kinds of projects I work on are better served without it. But I completely agree with pron when it comes to dismissing it as suitable for a large project with long time horizons.
Finally, another thing I have to fight as a Scala developer in discussing it's suitability is a perception that the Scala community is overrun with zealots who dismiss real industry concerns at the altar of cutting edge features. I think that is a real but overblown concern, but you are displaying all the hallmarks of that caricature. You are making my job harder. Please stop.
You have plenty of language design disasters to choose from if you want to have a language which cares about "industry concerns".
Even in Scala, the most painful warts and horrible "features" exist because of "industry requirements".
I could live without all those crazy conversions from Strings and numbers for instance.
Or all that crazy stuff necessary to support Java's idea of Generics.
Listening to the industry is exactly the reason why criminals can own machines by sending a web request with a bash function embedded in a bash variable to a remote server somewhere. In. 2014.
Until "industry" gets their shit together, their opinions are more than worthless.
a) Scala and the major.minor.patch version format predate semVer. You don't get to take the format that a lot of projects are already using and declare that it now has your particular semantics.
b) Scala does comply with semVer if you take "compatibility" to mean "source compatibility", which is the most natural interpretation; the spec talks about API rather and not about ABI.
c) Java's version numbering history is a total mess ("Java 2" is much older than "Java 1.8", for example). I really don't think industry is massively concerned about version numbering schemes.
No. The major.minor.patch version format predates either semVer or Scala and Scala's use of it may predate the codification of the semVer standard but most of that standard was very widely spread long before that. Most importantly, the expectation that only additive changes would bump minor versions and breaking changes would be indicated by a major version change has been near universal for a very long time.
Scala to this day, breaks source compatibility with minor version bumps of the compiler. That is not a natural interpretation.
Of course the industry doesn't care about version numbers. You could call it Scala Foo, then Scala Bar, then Scala Waz and no one would care in the least, but having expectations around and controls around source compatibility is very important to a certain segment of the development world and Scala has historically been very bad at that.
I think that Scala has gotten much better in this regard over time, but for a lot of its history it was bad at this. This has made some people rightly leery of using it in projects with long time horizons.
So I am not the one bringing new technologies into the project, if the customer didn't explicitly ask for them, even if I enjoy playing around with them.
That said, lack of algebraic types and other functional language features in C# is starting to have the same effect.
The day I'm not bringing new tech that no one asked for into my work is the day I either die or quit programming :)
Unfortunately that's a big stop sign for me to pursue .NET knowledge/career.
Not sure which kind of tool you refer to?
You can download Java + Netbeans here: http://www.oracle.com/technetwork/java/javase/downloads/jdk-...
Comes with integrated Maven dependency management, decent refactoring, JUnit etc ootb. Other additions available through built in package manager.
For large scale project? Not enough.
As for bringing new tech, I also do it, but not on the typical enterprise consulting projects where I spend most of my working time.
On those, customers only allow for "proven" tech.
For a very good reason (albeit the set of "proven" techs for them could be different than some of us)
Of course I try to use appropriate technology for given requirements. But if language X lets me solve the same problem in a clearer, more expressive way than language Y, and satisfies all the requirements, why wouldn't I use language X? The customer is the business expert, I'm the technology expert - I should be collaborating in the technology choices, not relying on them to make technical suggestions.
I wouldn't advocate it for production yet, I agree. I started using it for personal projects, though, and so far its lack of maturity mostly shows in documentation and harmless quirks. Not outright bugs.
It's 100% interop ensures that you can only implement bits and pieces in Kotlin, not necessarily the entire app. So you don't have to jump into it head first and commit yourself entirely.
Personally I would use it for bussines logic where the lack of LINQ / Streams / lambdas is hurting code readability. It is also very useful for plain data objects, since it removes so much of Java's verbosity.
Scala has got more things that Kotlin, there is a comparison of features: http://confluence.jetbrains.com/display/Kotlin/Comparison+to...
But I'm already happy with the advantages Kotlin has over old Java, Android's Java. It's fancy enough.
In IntelliJ at least, Scala "just works" out of the box. And IntelliJ is the tool that you'd expect to have the best Kotlin support, since as you say it's made by the same people. What about third-party tools - New Relic, or Takipi? What about third-party frameworks? (e.g. there's a wicket-scala project - it's not perfect but it takes a lot of the pain out of interop. I haven't used spring-scala but it seems like the same kind of thing)
> It's 100% interop ensures that you can only implement bits and pieces in Kotlin, not necessarily the entire app. So you don't have to jump into it head first and commit yourself entirely.
Scala's interop is actually more complete than Kotlin's - without existential types you can't express some types that it's possible to write in Java (e.g. nested bounds like <? extends T<? super...).
> But I'm already happy with the advantages Kotlin has over old Java, Android's Java. It's fancy enough.
If there were maturity or ecosystem advantages to Kotlin then I'd agree - after all, that's the reason I use Scala rather than Idris :P. But like I said, it seems to come with all of Scala's disadvantages, and fewer of the advantages.
And there's an element of the "blub paradox"; when I first started using Scala I wrote code that was more or less "Java without semicolons". Then I started using options. Then I started using case classes. Then I discovered that I could use the for/yield syntax to express some "wrappy" problems much more elegantly. Then I needed to make this work for collections, and I could abstract that. Then I discovered I could reuse the same code to handle a bunch of different abstractions, and that Scalaz already contained the most useful ones. And so on. Even today (after four years in the language) there are corners of Scalaz where I fear to tread, but at this point I'm confident that I'll need them sooner or later.
Not for Android, unfortunately.
There are plugin issues and it doesn't cooperate with Gradle all that great. I admit that I wasn't able to set it up :) okay, I wasn't hellbent on it and didn't try for days, but it was a bummer.
Otherwise I'd be using Scala gladly - after all, you can write Scala for living, while I don't expect Kotlin to appear in job ads anytime soon.
As long as Kotlin is not identical to javac, there is and never will be 100% interop.
> Scala has got more things that Kotlin, there is a comparison of features: http://confluence.jetbrains.com/display/Kotlin/Comparison+to....
While this is a valid point (although the comparison is probably outdated) we should keep in mind that years ago, Scala 1.0 (or something like that) was were Kotlin might be today.
There are reasons why Scala evolved from a "better Java".
(It still has the problems, of course, that WinForms was written back in 2002 and doesn't even use Generics, which would make the API a lot cleaner.)
- tail call optimization
- AOT compilation as part of the standard toolchain. No need to rely on third party vendors
- value types
- reifeid generics
- painless FFI with external code
EDIT: - Forgot about direct control over SIMD instructions.
All of those issues are being discussed for Java 9+ and have corresponding projects at OpenJDK.
1) Mono - deploy to every major mobile platform using a well-defined single-vendor pipeline.
2) .NET - unmatched performance on Windows.
Since they aren't visible at the JIT level, there isn't any guarantee that optimized assembly code will be generated.
Additionally, it is very dependent on which JVM it gets to be executed.
RyuJIT seems to deliver a nice, practical boost to performance.
.NET Native lets you sidestep (with several caveats) the JIT and start executing your code much more quickly.
And every other major release they seem to tune the GC to be harder/better/faster/stronger etc.
Because I read this article, and the article from the Jooq blog he references, and I can't see anything beyond one guy's preference for one thing, and Java 8 does it the other way.
a compromise would perhaps be to allow at least reified primitive generics so that List<int> would be a proper runtime type whereas List<Object> would be the runtime version of all reference types in List<T>.
Obviously, this would be a half-assed solution unless custom value types like point structs would also be allowed without boxing in similar scenarios. I'm not sure but I think that these things need pretty significant changes to the runtime.
My conclusion is that Java doesn't need this. It won't be elegant no matter what amount of lipstick is added. I even think some of the current features like lambdas are overkill. Instead, features should be added at the vm level to allow for other jvm langs to use them. A good functional language with good generics over primitives and proper value types would be awesome. F# is a good example of such a language (scala and clojure aren't)
This is actually pretty much exactly what the .NET runtime does. All value types get a separately-JIT'd version of the type, while all reference types share the same Object-based version. See section on implementation here:
http://msdn.microsoft.com/en-us/library/ms379564(v=vs.80).as...
Once it's been decided Java should get value types, generic reification became a more urgent necessity.
Something I really miss in C#/Java is a possibility to opt out of GC and use more stack allocation.
> Something I really miss in C#/Java is a possibility to opt out of GC and use more stack allocation.
The tradeoffs are often not what you think they are.
Not sure whether this was actually one of the reasons for allowing mutable structs to begin with, the use case is critical enough that it might well have been.
What I really want is for perf to be good while the code is still clean/readable/expressive/idiomatic. In Java/C# you must usually write idiomatic+slow and then refactor into fast kludges.
As an example, C#'s value types and generics with primitives makes that a lot better than in java.