10 ms·
In my experience most people don't like Java due to experiences they had before Java 8. This means they were used to the bloat, config as XML style world which
by boyter 7y ago
In my experience most people don't like Java due to experiences they had before Java 8. This means they were used to the bloat, config as XML style world which made Java a pain to write and slow to run.
Once I show them Java 11 with var keyword, lambda's and streams they start appreciating how modern the language has become. Then you throw in frameworks like javalin or sparkjava and suddenly they are not as hostile as they were before.
Honestly the only things I would really like out of Java these days are data classes and possibly native runtime compilation out of the box. Containers solve the latter issue, but id love to just build a binary and run it.
Do that and its on the same level as Go in many ways which nailed the tooling and deployment model, even if the language has issues. Java already has the tooling.
I suppose a decent syntax highlighter library like pygments or chroma would be nice too.
- vmurthy 7y ago> I suppose a decent syntax highlighter library like pygments or chroma would be nice too. Could you clarify this? I last worked on Java in 2016 but even at the time, we had eclipse settings that had Syntax highlighters. Am I missing something?
- boyter 7y agoHave a look at http://pygments.org/ http://pygments.org/ or https://github.com/alecthomas/chroma https://github.com/alecthomas/chroma where you can pass code into a library and it returns highlighted HTML. You can use Pygments in Java using Jython but its performance is questionable and can be incredibly slow when highlighting lisp code for example. Its a very edge case for most people, but seeing as I am working on a searchcode.com upgrade I need a fast highlighter. Currently I am spawning a background Go process using Chroma to take care of this for me, but if there was a decent Java library I would use it. None exist I am aware of that are even slightly up-to date.
- ngrilly 7y ago> Once I show them Java 11 with var keyword, lambda's and streams they start appreciating how modern the language has become. I wrote a lot of Java, but it was a long time ago. Could you share a bit of code representative of the modern Java 11 style you mentioned (var keyword, lambdas, streams, etc.)?
- deleted 7y ago[deleted]
- somerandomqaguy 7y agoNot the guy that you were asking but Trivial example: public static void assertIsSuperset(Collection<Object> superSet, Collection<Object> actualSet) { final List<Object> missing; missing = actualSet.stream().filter(x -> !superSet.contains(x)).collect(Collectors.toList()); if (missing.size() != 0) { /* Imagine some more verbose exception creation here, which is why we caught it in a list*/ } } The lambda is in the creation of 'missing': filter(x -> !superSet.contains(x)) A lot collections in Java 8 brought in a stream method which has some functional esqe methods. Filter is one of them, and if you look at filter's method signature: public interface Stream<T> extends BaseStream<T, Stream<T>> { /** * Returns a stream consisting of the elements of this stream that match * the given predicate. * * <p>This is an <a href="package-summary.html#StreamOps">intermediate * operation</a>. * * @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>, * <a href="package-summary.html#Statelessness">stateless</a> * predicate to apply to each element to determine if it * should be included * @return the new stream */ Stream<T> filter(Predicate<? super T> predicate); [SNIP!] } Predicate is an interface that has one method: 'public boolean test(T t);'. The lambda that I created conforms to that single method; accepting the generic object (x) and returning the boolean tested by '!superSet.contain(x)' The other way I've seen them used is to implement an anonymous version of an interface.
- WAHa_06x36 7y agoThat still seems very clunky and also very inefficient compared to what I'd do in Swift: func isSuperset<Type: Equatable>(superSet: Set<Type>, actualSet: Set<Type>) -> Bool { return actualSet.contains(where: { !superSet.contains($0) }) } What is all the noise about "collect"? Why allocate a while new list? What's with the "final"? And why do I have to type out obvious types in 2019?
- aardvark179 7y ago
- kjeetgill 7y agoAgreed on all points. You mentioned Go, so I'd like to add that Project Loom is the OpenJDK initiative to add green threads/coroutines to the JVM which I'd love. The tricky thing with "data classes" are that everyone wants something similar but different between the various terms: records, data classes, value types. Personally, what I want from this is essentially Lombock-style all-args constructors, equals, hashcode, and toString. Struct-like like embeddability and flat object-headerless arrays are cool but honestly more niche. I don't mind sucking it up and using unsafe.
- boyter 7y agoLoom is rather nice, but frankly I don't find the lack of co-routines something I miss. You can spawn hundreds of real threads a second so it is possible to write Go style code in Java if you really want. I may change my mind when I actually use it though. I don't mind what type of data classes they come up with. I just want to not have to write stupidly long constructors, multiple sets or chain-able objects when I want to populate some fields.
- kjeetgill 7y agoI've definitely had to fix servers that have choked themselves with thread abuse, so maybe it's ptsd. The fixes can be as simple as shrinking threadpools to needing substantial rewrites, so I still treat threads as resources requiring management. Green threads are nice because they let me separate logical execution from operating system resources. Unlike Go, Java will expose the ability to use a custom scheduler, so that should be nice! My personal pet usecase is actually the opposite. I want to isolate 5-10 "low priority" tasks to a single kernel thread to isolate how much damage misbehaving code can do.
- pjmlp 7y agoYou can already use custom schedulers with java.util.concurrent though.
- unscaled 7y agoExcept that the memory overhead for each thread is MUCH higher: the default would be 1Mb for most JVM implementation. Yes, you can change the thread stack size, but that's a global fixed size for all threads, so you can't make it to small, or you'll risk stack overflows. Meanwhile, Go is using dynamically growing stacks, starting at 2k.
- sandGorgon 7y agodid you ever try Kotlin ? whats your opinion there ?
- boyter 7y agoI have not. The only major thing I see in Kotlin over Java right now (I don't do Android development) is data classes. Everything else is either in the language or should be soon which makes me hesitant to invest the time learning it.
- pjmlp 7y agoI agree with you here, I think that Kotlin is settled for life in what concerns Android, given the sore state of Android J++ and #KotlinFirst announced at IO. Outside Android, we can enjoy modern Java, which makes Kotlin just yet another language capable of targeting the JVM.
- agumonkey 7y agoI may work with java soon, so I was reading about Spring and it was yet again a dive into insane amount of verbose over engineering that I ran away from years ago. It's true that post 8 Java becomes palatable. And someone on reddit just showed me this piece of stats: https://www.jetbrains.com/lp/devecosystem-2019/java/ https://www.jetbrains.com/lp/devecosystem-2019/java/ 83% on java 8, java 11 nicely going up I pity those forced to work with old techniques
- maltalex 7y agoI write quite a lot of Java, and I have to admit I never “got” Spring. I’d much rather have explicit boilerplate code (preferably in library form as much as possible) than complex, invisible magic. The latter is “easy”, but the former is “simple”. In most cases, “simple” is more important.
- unscaled 7y agoBut Spring gives you the best of both worlds. A lot of verbose code (as annotations and class inflation instead of explicit boilerplate) and inscrutable magic.
- arethuza 7y agoIf only we could all agree on what "simple" means - a lot of "enterprise" code I've seen would sweep vast amounts of complexity into hard to spot places to that you could have a small thing that people could point at and say how simple the one visible bit was, ignoring the vast amount of complexity lurking under the surface somewhere and invoked by more or less magical means.
- nurettin 7y agoI'd say there is no upside for the complex invisible magic. Half the time you have to run the application and pray that the configuration beans you've placed are working and if not, you are pretty much in trouble. Perhaps you missed a step in adding a configuration decorator in your application or configuration class, or used some deprecated method or used some incorrect class in the class hierarchy for the bean you want to return.
- pvg 7y agoThe additions and improvements are great but I think we're developing a kind of shared 'Modern X' fallacy. Modern Perl, Modern C++, Modern PHP, Modern Java, etc. The 'modern' facilities and the styles and efficiencies they enable are invariably terrific but you can't comfortably and effectively make use of them without having to know the bulk all the non-modern stuff. Which ends up limiting the appeal to the sorts of people who were prepared to put up with pre-modern to begin with.
- cursork 7y agoI agree with this to a large extent. A new codebase in the latest Java/whatever can be OK. But most of the time I feel like it's dealing with the same bad code, with just a smattering of nice syntax on top. I started learning Perl in 2007; after it was no longer popular, but also around the time that the principles/practices that became 'Modern Perl' were becoming popular in the community. I think there is a difference between the two though. Java was always a language which required a lot of ceremony and typing to get anything done at all. Perl was always focused on expressivity. Modern Perl was a case of learning from past mistakes and consciously avoiding some of the more egregious code the language easily afforded. Modern Java is more a case of Java playing catch-up to the more expressive languages out there. One is applying constraints on your coding style, the other is trying to lift constraints. Both are trying to reach some middle point. But! I agree that no company writes purely 'Modern Perl' - you will have to deal with some terrifying code at some point. So. I agree with the concept of the 'Modern X' fallacy, but I would say that dealing with non-modern code is pretty normal, and people who are OK putting up with the pre-modern code may be some of your best employees. I suffer from rewrite-it-all syndrome myself sometimes, but it's something I try to avoid. Code that frustrates me, isn't necessarily bad. (If it helps contextually, I'm - at heart - a Clojure programmer.)
- Nursie 7y agoBig fan of sparkjava for no-nonsense HTTP services. The days of tomcat-for-everything were not fun as someone who only occasionally dabbled in java back then. So I have to build this as a special type of jar and then set up this other, rather opaque, set of stuff and deal with all sorts of nonsense ... Now? get("/hello", (a,b) -> "Hello World"); And we're done...
- butteroverflow 7y agoThat sure looks nice, but how often do you write services which return a single constant string? I like to judge languages/frameworks based on more representative snippets.
- unscaled 7y agoI think this is not about showing off the easy case, but rather the straightforwardness of the framework. I haven't used spark myself, but I used frameworks quite like it (Jooby, Rapidoid, Ktor) in Java, as well their counterparts in Nodejs (Express, Koa) and Go ("net/http" + some router). The applications certainly got a lot more complex than that, but we never found ourselves in need of a magic annotation that you can't step through with your debugger. This is all about simplicity. It's pretty clear how a get() function on the router which takes a route and a callback works, but it requires some work to understand how Spring magically scans all your classes looking for annotations and then builds parser based on that. It's quite unclear where all of the routes are coming from (since they can come from a class just about anywhere). You suddenly need special tools. And the worst thing that suffers is transparency. Ctrl-clicking/Cmd-clicking on an annotation in your favourite IDE never tells you what it does. In comparison, a second-order function is a vastly simpler and more grkoable beast.
- Nursie 7y ago> That sure looks nice, but how often do you write services which return a single constant string? The point was just to show that the http server aspect of it is trivial to set up. You can hook in whatever you want from there.
- Nursie 7y ago
- twsted 7y agoThis is not the only reason. Who started using Java way before Java 8, used to experience serious issues about memory usage and performances in the JVM. These memories struggle to leave.
- sebcat 7y agoEspecially on 32-bit JVMs. Still have nightmares.
- sonnyblarney 7y agoI find the Java love/hate intriguing, I personally like the ideal of 'getting the job done'. Pre Java 8 is just fine, I don't think it's materially changed, I think what has changed is perception i.e. the realization that all that Enterprisy cruft 'does not equal' Java - nor do wee need FactoryFactor patterns. My wishlist: - Stream syntax was nice, but a little clumsy - In addition to data objects, some kind of 'un-typed' object (better than a Map) for dealing with json-ish type data, right in the syntax. - First class functions instead of lambdas - Async notation as a better way to express threads, or even combining within the same thread - Union types For compilation, you should check out Graalvm, which has some neat new features there.
- Nursie 7y ago> Async notation as a better way to express threads CompletableFutures? You don't deal directly with threads in java (unless you want to) these days.
- xrisk 7y agoI was checking out Spring recently. The hello-world sample turned me off at once [1]. It's so much more clunky than something equivalent in Python/Go/what have you. [1]: https://spring.io/guides/gs/rest-service/ https://spring.io/guides/gs/rest-service/
- Litmus2336 7y agoWhile I agree with you that Spring is clunky, if you're making a simple application I don't think anyone will recommend Spring. Where Spring shines is enterprise. When you have 600k concurrent users it's just something I can trust. Other solutions can work too, but we value the stability.
- vimslayer 7y agoThat sounds a lot like what people are saying about PHP and its newer versions. But the thing is, now that we have great alternatives (Kotlin, C#, Scala, Go, Dart...), what does Java have that those don't?
- stevoski 7y agoI can’t recommend sparkjava enough. It is the only Java web framework I’ve encountered whose “quick start guide” is actually that: a guide that gets you started in minutes, not days. The fully working “Hello world” app is 5 lines of code. I built my profitable, bootstrapped B2B SaaS using sparkjava. You can find sparkjava here: http://sparkjava.com/ http://sparkjava.com/
- fniephaus 7y agoRE native runtime compilation: have you had a look at GraalVM's native image: https://www.graalvm.org/docs/reference-manual/aot-compilation/ https://www.graalvm.org/docs/reference-manual/aot-compilatio...
- IloveHN84 7y agoGraalVM works with Java 8, Java 11 isn't fully implemented
- pragmaticlurker 7y agocheck out what 'auto' does from C++11 onwards then, oh and smart pointers too: memory management is no hell anymore
- StreamBright 7y agoI think it is certainly part of it. I also don't like Java because best practices include hiding everything inside objects and developers are generally against using simple functions. I also dislike how leaky abstractions are common in average Java code and the unnecessary verbosity. Java 8 helped with many of these yet, it is uncommon to see Java 8 syntax in most sources I work with. Many large companies just migrated or in the middle of migration to Java 8.
- unscaled 7y agoJava 11 is obviously much better than Java 8, which is still leaps and bounds ahed of Java 6, itself an improvement over Java 4. You'd see the same in every language. Java's problem is that for many years it used to be the slowest car around. Maybe this was one of the things that helped Java become the undisputed ruler Enterprise Inc. but now it's got a lot to catch up with, and even though the pace has picked up since Java 9, it's far behind its competitors. Everything you mention (var, lambdas, streams) and everything you might mention when Java 13 comes out (switch expressions, text blocks) is just too little, too late. Yeah, var is a lifesaver if you have to use Java, but compare the limited type inference it brings to the table with almost any other competing language (Kotlin, C#, Scala or Swift) which at the very least can do a return value inference. Likewise, streams are long due, but the syntax is horrible and the repertoire of built-in operations is meager, and since Java does not support extension functions like the rest of the languages mentioned here you can't extend them gracefully. If you take one of the examples given here: var grades = school.students() .stream() .flatMap(student -> student.grades() .stream() .map(grade -> new NamedGrade(student.name(), student.grades()) .filter(x -> x.grade() > 60) .collect(Collectors.toList()); Kotlin goes the same route, but makes it little more natural to use: val grades = school.students .flatMap { (name, grades) -> grades.map { NamedGrade(name, it) }} .filter { it.grade() > 60 } .toList() Besides simply more natural syntax, get the special 'it' variable, destructuring, more operations and Now take C#, a language had something "Streams" since version 3.0 (released 7 years before Java 8): var result = students .SelectMany(student => student.Grades.Select(grade => new { Name = student.Name, Grade = grade })) .Where(record => record.Grade > 60); Where you get anonymous records - you don't need to define a new type anymore. Or with LINQ: var result = from student in students select from grade in student.Grades where grade > 60 select new { Name = student.Name, Grade = grade }; You get a highly readable built-in query language as well.
- rjbwork 7y agoQuick nitpick. Both of the C# examples are called LINQ. The first is called the "method syntax", the latter is called the "query syntax". The query syntax is transpiled into the method syntax before compilation.
- Macha 7y agoLike with C++ though, chances are you will not be working on a "modern" project and will have to deal with patterns like random nulls, APIs based on extending framework classes etc
- ar_lan 7y agoJavalin is a bit of a cop out because it's not strictly Java. I agree with modern Java improvements for the most part, especially if you are including Kotlin in that ecosystem - I really enjoy writing Kotlin. However, I've professionally switched to Go and really wouldn't want to go back to Java much. I already think Go is a bit bloated, and I still feel like Java (even w/ the latest modern features) still gets incredibly bloated.
- ryuukk_ 7y agoproblem isn't that stuff, it is how java is engineered, it was made for the 80's gaming industry is huge, but you can't with java because autoboxing everywhere, no value type, and no specialized generics same for serverless, you can't because you have to ship heavy runtime same for machinelearning, you can't do math because lack of value type etc etc etc Java tried to fix all problems, but they forgot the essential stuff, performance and efficiency