Hacker News new | past | comments | ask | show | jobs | submit login

Either it's the people who write Java, or something intrinsic in the design of the language itself that drives people to write code in this extremely verbose way. I've always leaned towards the latter...



A bit of column A and a bit of column B. People who write Java are exposed to rampant overuse of design patterns when looking at examples of a) what the community considers Good Java and b) all over their internal projects. This is partially because Java lives, by design, in a Kingdom of Nouns and partially because there's just no good way in the standard language / library / toolchain to do some things without going really pattern heavy.

For example, assume I've got a list of students, and I want to show all the ones who haven't taken at least one exam, sorted by last name. Here's the relevant pseudocode in Rails:

class.students.select {|student| student.tests.inject(false) {|acc, test| acc || (!test.taken? )}}.sort {|a,b| a.last_name <=> b.last_name}

That just flows from my keyboard as a Ruby/Rails programmer, is pretty much instantly comprehensible to other Rails programmers, and (while others might disagree with stylistic choices, variable names, or whether to use that weird &syntax to do the sort) would be considered "good enough Rails code to ship."

I will take the liberty of pasting my Java implementation into a gist -to avoid breaking HN:

https://gist.github.com/3760402

A nice, svelte 38 line method, which will be reused via copy/paste a hundred places in my codebase.

Incidentally, at my previous Big Freaking Enterprise job, the user need "Make a page for a class where we can see all students who haven't..." would get quoted to them as "No problem, that will cost you $1,000. Are we green-lit to implement or do you want docs written first ($250)?", because the core logic I've shown you is the tip of the iceberg of how sucky that experience is going to be. We haven't even started with the XML files and annotations required to hook the new actions together yet. By comparison, as a Rails developer, in lieu of getting you to sign off on a $1,000 line-item to your next invoice I'm inclined to show you a totally working page and ask you "Is this what you wanted?" because implementing it is easier than talking about implementing it.


I don't want to play code golf with you, because I think your point is generally valid, but you can happily and idiomatically reduce the Java method itself to 10 lines with some sympathetic scaffolding from the other classes (this is actually how a lot of code in our game is implemented rather than some theoretical optimum):

  public class Student implements Comparable<Student> {
    @NotNull public List<Test> getTests() { ... }
    @NotNull public String getLastName() { ... }
    @Override public int compareTo(Student that) {
      return getLastName().compareTo(that.getLastName());
    }
  }

  List<Student> studentsWhoHaveNotTakenAtLeastOneTest() {
    TreeSet<Student> studentsMissingAtLeastOneTest = new TreeSet<Student>();

    for(Student student : getStudents()) {
      boolean allTestsWereTaken = true;
      for(Test test : student.getTests()) {
        allTestsWereTaken &= test.isTaken();
      }

      if (!allTestsWereTaken) {
        studentsMissingAtLeastOneTest.add(student);
      }
    }

    return new ArrayList<Student>(studentsMissingAtLeastOneTest);
  }
The point I'm (perhaps ineptly) making is not that Java isn't all that verbose (because it obviously is) - rather it's that you don't get much of a stack of abstraction by default. If you don't take the time to implement that abstraction, you're going to have a bad time, but if you do, it's not appalling.


that, or even 10 lines, is still several orders of magnitude more code than how you do it in a dynamic language like ruby or python


It's not really dynamism so much as a functional outlook. Here it is in Scala (probably with a healthy number of syntax errors, and certainly with a whiff of inexperience):

  def studentsWhoHaveNotTakenAtLeastOneTest = getStudents.filter{s => s.getTests.filter{t => !t.isTaken}.size > 0}.sorted
You could get a similar amount of code in Java using something like FunctionalJava but that's not really a fair comparison, because patio11 is illustrating Java as it's spotted in the wild, and thus so am I. But with appropriate libraries and implementation patterns you can certainly write concise Java if you so choose.


student.tests.inject(false) {|acc, test| acc || (!test.taken? )}

can be reduced even further using the all? method

!student.tests.all?(&:taken?)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: