Live data from Hacker News

Love It or Hate It, Java Continues to Evolve

azul.com

71–80 of 156 posts

Re: Love It or Hate It, Java Continues to Evolve

#71

Earlier quoted context omitted.

Not the guy that you were asking but Trivial example: public static void assertIsSuperset(Collection superSet, Collection actualSet) { final List 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': filt…

That still seems very clunky and also very inefficient compared to what I'd do in Swift: func isSuperset (superSet: Set , actualSet: Set ) -> 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?

Yeah, the collect isn't really needed, you could easily use a reduce to calculate the value.

Re: Love It or Hate It, Java Continues to Evolve

#73
post #34
post #17

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 a…

Big 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...

Since we are hiding the rest of the app, in spring boot + kotlin that would be:

    @GetMapping("/hello") fun hello() = "Hello, World!"

Re: Love It or Hate It, Java Continues to Evolve

#74
post #17

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 a…

I 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.

Re: Love It or Hate It, Java Continues to Evolve

#75
post #17

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 a…

Java 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.

Re: Love It or Hate It, Java Continues to Evolve

#76
post #34

Earlier quoted context omitted.

Big 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...

Since we are hiding the rest of the app, in spring boot + kotlin that would be: @GetMapping("/hello") fun hello() = "Hello, World!"

That's a nice try, but the rest of the app would be[1]:

    import static spark.Spark.get;

    public class HelloWorld {
        public static void main(String[] args) {
            get("/hello", (req, res) -> "Hello World");
        }
    }

[1] http://sparkjava.com/

Re: Love It or Hate It, Java Continues to Evolve

#77
post #66

"James Gosling, the Father of Java, described it as a Blue collar programming language." I wonder what can be considered a white collar programming language which is actually used a lot. Erlang? ES6 with ever changing front end frameworks?

Python or Ruby I'd say, Erlang's a little bit too unique I think for that analogy

Re: Love It or Hate It, Java Continues to Evolve

#78

Earlier quoted context omitted.

Since we are hiding the rest of the app, in spring boot + kotlin that would be: @GetMapping("/hello") fun hello() = "Hello, World!"

That's a nice try, but the rest of the app would be[1]: import static spark.Spark.get; public class HelloWorld { public static void main(String[] args) { get("/hello", (req, res) -> "Hello World"); } } [1] http://sparkjava.com/

It is indeed a nice try, and the rest of the app would be:

    @SpringBootApplication
    @RestController
    class DemoApplication{
     @GetMapping("/hello") fun hello() = "Hello, World!"
    }

    fun main(args: Array) {
     runApplication(*args)
    }
And this taught me that the best sinatra clone in java isn't really worth it in terms of lines of code saved (we save what? 3 lines of code? 6 with the imports?) when compared to a full-blown web framework like spring boot.

Would you care to do another one where we return a json response? I'd bet you will need a json mapper class for complex objects whereas I will return a dataclass instance and it will just work.

Re: Love It or Hate It, Java Continues to Evolve

#80
post #34

Earlier quoted context omitted.

Big 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...

That 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.

I 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.

Post reply on HN