20 ms·
" However, we had a strong aversion to using Java itself, so the real short list was Scala or Clojure." Sadly they couldn't articulate any actual problems with
by kisstheblade 11y ago
" However, we had a strong aversion to using Java itself, so the real short list was Scala or Clojure."
Sadly they couldn't articulate any actual problems with Java...
I find it weird that so many developers focus on the "writability" of the language. I mean stuff that java gets criticized for, like verbosity etc. Which I don't even find so bad especially since the newer jdk versions.
But in my opinion the _readability_ of the result is the most important factor. I rather read copy/pasted code than some smart clojure onliner which nobody dares to touch or really understands.
You only write the program once, but you have to read it over and over again when maintaining it and developing new features, and java's maybe a little verbose syntax really helps here, and also the fact that there really is only one way to do a thing (unlike eg. perl).
The tooling, documentation, frameworks, libraries and runtimes are all top notch with java. All other languages seem to have problems in one (or more) of these areas.
- vosper 11y agoThe small amount of development I've done with Clojure convinced me that you just can't ignore Java - you're going to end up spending time reading Java docs, and debugging Java stacktraces. If you really dislike Java I don't think choosing Clojure is a great option, either (I don't know about Scala).
- tlrobinson 11y ago(Metabase dev here) > you're going to end up spending time reading Java docs That's actually a benefit IMHO. If no one has created a nice Clojure library or wrapper for something you want to do it's at least possible to use the massive number of existing Java libraries directly from Clojure.
- kisstheblade 11y agoOuch, got downvoted in under a minute. Guess it's not cool to say anything positive about java! :) I still would have liked it if the authors of the article had said something about why they had a "strong aversion" for java.
- hughw 11y agoI'm not a down voter, but there have been volumes written about the pros and cons of Java. Every possible corner of every possible argument has been explored ad nauseum. I'm grateful they didn't waste my time rehashing the endless arguments. As far as I'm concerned, Blub beats both of these languages.
- jolux 11y agoForced object orientation?
- melted 11y agoI don't have a problem with Java per se. I do have a problem with architectural masturbation the Java community often engages in. I mean both the FactoryFactoryFactory kind and the "you can't instantiate anything directly" (IoC/AOP) kind. I have a feeling that one of the reasons e.g. Go is becoming popular is because it doesn't encourage (or in fact even allow) such idiotic programming approaches.
- a-saleh 11y agoIn my experience, the readability of Java is not that great, perhaps due to verbosity. Especially when you want to create a DSL with some type-safety guarantees. Wrapping a head around a factory that is configured by fluent-like-api, with interfaces scattered around 10 different files usually took me longer than understanding idiomatic clojure. When I was working in clojure, only thing I was really missing was the type-checking. But when I work in java, i miss the REPL much more, than i missed type-checking in clojure :)
- incepted 11y ago> But when I work in java, i miss the REPL much more, Both IDEA and Eclipse have had a REPL for a decade, not sure what exactly you were missing(?).
- a-saleh 11y agoI missed mostly three things: 1. simple data definition. Clojure has EDN, python has nice syntax as well, and javascript has json. 2. pretty print 3. succinct function definition/execution, and standard array of functional tooling (map, filter, reduce, etc) Maybe the 3rd thing did get better with Java 8?
- jerf 11y ago"Sadly they couldn't articulate any actual problems with Java..." The first thing they said about Go applies to Java: "Go felt promising but too low level for us to express our query language productively." You certainly can write that sort of code in Java, as evidenced by the fact that many people have and continue to. But you can get a very big win on that sort of code in a lot of other languages, especially if you're resource-constrained.
- lemevi 11y agoHow is Java low level. Java is a high level language. What is "low level" about Java? Do you mean statically typed makes it low level? No it doesn't. It makes it safer though. Low level means direct access to hardware and having to deal with network protocols manually and shit like that. None of which you almost ever do or would want to do with Java considering it runs on a cross platform runtime mostly isolated from the actual OS of the host machine.
- j-pb 11y agoJava has a series of control mechanisms that originate from idiomatic assembly. for, while, if, variables. In clojure for example you rarely use these low level constructs. What is simpler to read? Which one is more high-/low-level List<Integer> even = new List() for(int i = 0; i < 100; i++){ if((i%2)==0){ even.add(i); } } return even; or (filter even? (range 0 100))
- diek 11y agoThe GP qualified that this is better with newer JDK versions. For instance, in Java 8 you can do: IntStream.range(0, 100).filter(i -> i % 2 == 0);
- j-pb 11y agoI find i -> i % 2 == 0), still less readable than even?. But let's step up the game a bit. Let's produce a sequence of the form [true false false true true true false false false false ...] of exact length 1000. (take 1000 (mapcat (fn [i] (repeat i (odd? i))) (range)))
- pjlegato 11y agoAfter you've been writing it for a while, reading Lisp / Clojure at a glance is not nearly as scary as it seems at first. You get used to it, and that one-liner becomes a paragon of elegant simplicity rather than a strange collection of symbols. It's just a different mode of scanning than what we've become accustomed to by working in mainly ALGOL-derived languages. With practice, it becomes second nature (and ALGOLs seem needlessly verbose by comparison :)
- bsuh 11y agoI've tried unsuccessfully to learn the zen of Lisp. When you read a Lisp one liner, to me it seems like there are many implicit details you have to hold in your head. "Ok after this parenthesis now you have a list of maps keyed by symbols with string values. Ok go up one parenthesis and now it's transformed to a list of maps with..." Continue unwrapping for 3 levels. Get messaged by coworker. "Ok. Where was I? Fuck." Rich Hickey said something along the lines of "If a function only deals with mutability in local variables (for performance), it's still a pure function". I prefer reading imperative functions that are still pure in that sense and spell out each transformation line by line to reading highly compact code written in powerful languages. Maybe I'm just dumb.
- nudpiedo 11y agoWhy dumb? Perhaps you only need longer time to adapt to the new status... until the new way to structure the code becomes your default way to present functions.
- artifaxx 11y agoWriting is the key, I wrote in 10 programming languages and lisp still looked alien to me. It was only once I was forced to write out examples in a programming languages class that it started making sense. You really have to try writing in something novel like a lisp dialect to assess whether or not it makes sense!
- j-pb 11y agoClojure allows me to express thoughts that I wouldn't know how to express in for, while, if, variables and objects. And on readability, what do you prefer? List<Integer> even = new List() for(int i = 0; i < 100; i++){ if((i%2)==0){ even.add(i); } } return even; vs. (filter even? (range 0 100))
- incepted 11y agoOf course, dynamically typed languages will win on one liners against Java but in the long run, the absence of types can really bring an entire code base (and project) down, which is why Clojure is hardly used at all and why Java is everywhere. Besides, Clojure doesn't even win in the one line department against modern JVM languages (e.g. Kotlin).
- arohner 11y ago> which is why Clojure is hardly used at all and why Java is everywhere. Surely that has nothing to do with Java being 20 years old, and Clojure 1.0 being 6 years old? > Clojure doesn't even win in the one line department against modern JVM languages (e.g. Kotlin). Example, please.
- incepted 11y ago> Surely that has nothing to do with Java being 20 years old, and Clojure 1.0 being 6 years old? Lisp has been around for 50+ years, hasn't really helped its popularity much. But I'm willing to bet with you that in 14 years from now, Clojure will have even fewer users than it has today. > > Clojure doesn't even win in the one line department against modern JVM languages (e.g. Kotlin). > Example, please. Here it is in Kotlin: (0 .. 20).filter { it % 2 == 0 }
- tomjen3 11y agoThis may be due to Android being limited by Java 6, but I find Java code to be so verbose that it hurts readability. Unnecessary try/catch/ignore just to close a resource, tons of factories, classes with static methods because you can't add the functionality to string, etc. What weirds me out is that they didn't even consider Kotlin an option, since it is essentially a language so that you can code Java, but without the javaness.
- GFK_of_xmaspast 11y agoYou might call it 'unnecessary' but if that exception's going to be thrown somebody's going to catch it, and you don't want it to be the android runtime.
- lostcolony 11y ago'Couldn't articulate' vs 'didn't articulate' are two different things. The tooling, documentation, frameworks, libraries, and runtimes are all there if you want to use them in Clojure, too. So that's not a point in Java's favor, just the JVM's favor. It is quite possible to write reasonably readable, terse, correct Java programs. I rarely ever see them in the wild though; what I've mostly seen are klugey Spring or JavaEE based monstrosities that are horribly inefficient, and prone to hard to debug concurrency issues. The average results seen with the language -is- a consideration; while it's hardly scientific (the teams choosing Java tend to be from all walks, and disproportionately from large enterprise teams where no one gets any real say in the matter, that's just the common denominator that management has allowed; the teams choosing, say, Clojure, tend to be smaller and made of good developers who are intellectually curious, and have found themselves in places they can make that decision, so obviously the average for the latter will likely be better), it's still a consideration. If you've written in a wide range of languages, you've -seen- this in yourself; what the language makes easy vs what it makes hard influences how you do things.
- wwweston 11y agoFor me, readability is directly tied to good abstractions (and meta/programming facilities for making good abstractions) and a certain degree of conciseness. If I have to read 5-10 lines of intermediate code to figure out what's going on, it's less readable than if there's a short expression. Some languages seem to be driven by fear that if you provide programmers powerful facilities for abstraction that rise to the level of augmenting the language that developers will no longer be able to figure out what's going on without reading a lot of code, so they solve this problem by forcing developers to write (and therefore read) a lot of code. Java seems to be one of those languages.
- lmm 11y agoI find the readability is where Java's verbosity really hurts it. E.g. if you bring up the horribly verbose getters/setters in Java many people will respond that you can autogenerate them - which is true as far as it goes. But you can't "autoread" them, and if you have a thousand getters/setters of which ten provide different functionality to the standard field access, that makes the code very hard to read.
- logn 11y agoI don't find much validity to this argument that constantly comes up. Out of the box, you have two options and neither are bad... (1) Make your variable package/public/protected scope and refactor one day if you have to. (2) Use getters/setters, possibly with shorter names (if your fancy framework allows that) and more terse formatting. Is this so bad? int size(){ return size; } void size(int newSize){ size = newSize; } The setter shouldn't be so common anyhow because immutability is better. Besides, if you have a thousand getter/setters then your problem might not be Java.
- lmm 11y agoMost coding standards don't like that, and if you can't autoformat your code then you have bigger problems. I do agree that some of the problems are cultural rather than inherent to the language, but even if we do that, public class Potato { private final int size; public Potato(int size) { this.size = size; } int size() { return size; } } makes poor reading in comparison to class Potato(val size: Int) (I didn't mean a thousand getters/setters in a single class, but across the codebase as a whole)
- dragonwriter 11y ago> I find the readability is where Java's verbosity really hurts it. I'd agree, but on the JVM there are plenty of statically-typed languages with clean interop that permit more concise expressions than Java, so I don't see conciseness alone as a reason to go to a dynamic JVM language. (That said, Java is getting better at this over time, though its still, to me, a pretty big negative for Java.)
- cobaltblue 11y agoClojure wins on readability as well as writability. The easiest way it does that is by drastically reducing the amount of code you have to write for whatever random thing you'd otherwise do in Java. It opens the door even further for additional savings compared to other languages in a similar place like Python or Ruby by providing macros. Freedom from the Kingdom of Nouns alone gives you a big win in readability. Naming things is hard, and when the thing you care about isn't the Class but the Method then bothering to name a wrapper Class is additional overhead, an extra "what is this in my code?" that you need to make room for in your brain -- additionally it's common practice in Java world to put that Class in its own file all by itself, often in a totally different namespace, and often physically far away from where it's actually used when looking at the files on the filesystem, which further increases the cognitive load of knowing where your code lives. IDEs in the land of Java are helpful only because they are necessary because without them the cognitive load is just too much for any reasonably complicated project. Freedom from mandatory static typing of the sort Java has saves you from pointless class wrappers, pointless POJOs that must have names and live in their own files and namespaces, you are free to just use maps of keywords to values. Free to work with the data directly rather than an ad-hoc aliasing scheme that might decide to hide things you need or surprise you with nulls. When you want protocol or interface adherence, it is there for you, but it is not mandatory for everything. Maintaining Clojure is easier because there's less of it. A new hire can be pointed to your code of n files and told to spend a week reading and playing in the REPL, versus pointed to n2 files and told to spend a month reading and inserting breakpoints here and there to understand all the chaotic flows across what and where. You have a legitimate shot at picking 10 random Clojure files out of the project and understanding a bit about the data flows in them in relationship to the project as a whole, but in Java you're going to need a lot more context, especially if you get unlucky and pick out 10 MyCustomException classes. What is there in Clojure can be very dense, but it can be apparent in code review when you went too far, and then it's easy to refactor and you don't need any auto-refactor tools. You just substitute expressions, add comments, and name only what needs to be named, you can do it all without constantly needing to restart your program because (unless you're using JRebel) you added a function here or changed a parameter there. Java is good for risk-averse corporations -- a single average Dev on an average size team can't do very much, many corporate programmers average around 1000-2000 lines of code per year* even with their IDEs helping them, and because of that they can cheaply be replaced or moved to another part of the project.
- jiyinyiyong 11y agoWell, not everyone thinks Java is easy to read. I've doing my job with JavaScript and CoffeeScript for more than two years and I still hates JavaScript, let alone Java. And CoffeeScript is way better than it, even it's simply just some syntax sugars. I'm learning Clojure and it's even more expressive than CoffeeScript and that's why I like reading Clojure.
- lectrick 11y agoYes, Java is a mature language. But any perusal of rosettacode.org is fairly indicative that other languages, while less mature, have adopted some good ideas. For example, here's Quicksort in both Java and Elixir: public static <E extends Comparable<? super E>> List<E> quickSort(List<E> arr) { if (!arr.isEmpty()) { E pivot = arr.get(0); //This pivot can change to get faster results List<E> less = new LinkedList<E>(); List<E> pivotList = new LinkedList<E>(); List<E> more = new LinkedList<E>(); // Partition for (E i: arr) { if (i.compareTo(pivot) < 0) less.add(i); else if (i.compareTo(pivot) > 0) more.add(i); else pivotList.add(i); } // Recursively sort sublists less = quickSort(less); more = quickSort(more); // Concatenate results less.addAll(pivotList); less.addAll(more); return less; } return arr; } now Elixir: defmodule QuickSort do def qsort([]) do [] end def qsort([pivot | rest]) do { left, right } = Enum.partition(rest, fn(x) -> x < pivot end) qsort(left) ++ [pivot] ++ qsort(right) end end The advantage here is NOT just an "economy of typing."
- Nicolas0682 11y agoThe readability argument is overused and maybe misunderstood to me. An experienced programmer is supposed to know the language well as well as the API and frameworks. From my experience Java is quite verbose and the standard frameworks are among the most complex. It is typical for a clojure/scala/python program to require 1/2 or 1/3 the lines of codes than Java. And they require much less configuration files and annotations. How much time a developper spend to read his operating system code? How much time a developper spend to read the API implementation code of his language or even the framework ? No time because the code is great, work as expected and doesn't require to be read all the time. That's what a more expressive language provide. At greater set of standard language construct, API and frameworks that allow you to express the same in a much more concise way. This is much easier to read because the fundations are rock solid and the meaning of a function doesn't evolve over time, it is also nearly bug free. You reduce the accidental complexity. When you choose a less expressive language like Java, even with the most advenced frameworks you have much more unreliable custom code. You are in fact increasing the readability issue, not reducing it. Sure there the fact that many more developper master Java and the associated frameworks than say Scala or Clojure. But this also act as a filter. You can do the same thing with a team of 5 experienced clojure developpers than with 20-30 java dev. A part come from the language expressivity itself. A part is that it is much more likely to get bad developpers in Java that will mess your code and make you loose time. It is easy to find Java dev, a bit less to find great Java developpers. Another part is that the bigger the team, the more is lost in communication, meetings and politics than actually doing things. So that your choice ! Do you prefer 5 clojure dev, maybe paid 20-30% more or 30 java dev with 5 managers (paid 20-30% more) competiting to get budget and projects ?