views:

256

answers:

3

I can perfectly see why Clojure is really good for concurrent programming. I can see the advantages of FP also in this regard.

But clearly, not every line of code that we write is part of a thread or needs concurrent access. For those parts of the code (the more simple and sequential piece of code) what is it that Java really missed that Clojure provided?

Were features like Multimethods, Dynamic binding, Destructuring bind really missed in Java?

I supposed my question can also be framed as:

  • If Clojure did not have the Concurrency features that it had and the whole Immutability/Mutability issue was not of our concern, then what other features Clojure provides that would make you use it instead of Java ?
+1  A: 

Well for one there is generally a lot less "ceremony" in Clojure. Languages like Python and Ruby have this advantage over Java as well (thus the popularity of JRuby, Jython).

But note there are times when verbosity cannot be avoided in Java though there might be a clear pattern. Clojure's macros are a huge win here- even over other similarly dynamic languages.

Another thing to consider is that Clojure programs tend to be concurrency safe. So if you decide down the road to make a particular application concurrent, it won't be too painful. Without making alot of decisions up front this will be considerably more difficult with Java.

Also wondering if Clojure would have a clear advantage over Java if it lacked strong concurrency primitives and immutability is kind of like saying, "Well what if Clojure wasn't Clojure?"

dnolen
+18  A: 

Were features like Multimethods, Dynamic binding, Destructuring bind really missed in Java?

Yes. Also...

  1. First-class functions. Delicious first-class functions. This isn't just an FP thing. There's a good reason people are clambering for closures in Java 7.

  2. Code-is-data. This is the benefit of any Lisp. Lisp code isn't just blobs of text you feed into the mouth of a compiler and never see again, it's structures of lists and vectors and symbols and literals that you can manipulate progammatically. This leads to powerful macros and first-class Symbols and lots of other goodies. It leads to a highly extensible and powerful language.

  3. Clojure has better control and looping constructs and the ability to create your own via macros and first-class functions. Java has for and foreach and while (and didn't even have foreach for years). Clojure has map, filter, reduce, mapcat, lots of do forms, lots of if and when forms, list comprehensions via for, and so on. If these didn't exist, you could write them yourself. In Java you get to wait a decade for a committee to (maybe) approve such features.

  4. Minus those dealing with static typing, all of the features set for Java 7, Clojure either already has or could have trivially. "Automatic resource management", Clojure has as with-open. "Language support for collections", Clojure (and Ruby, Perl, Python...) have already. "Strings in switch", Clojure has more powerful case-like constructs like condp, and whatever else you can think up. You could write any of these yourself in a dozen lines of Clojure.

  5. Concise syntax for lists, maps, arrays, sets, sorted sets, sorted maps etc. and nearly interchangeable use of them all thanks to the seq abstraction. Literal support for regexes, characters, anonymous functions, etc.

  6. Java has mandatory checked exceptions, which are annoying; Clojure doesn't.

  7. Java syntax is verbose and irregular. Clojure syntax is concise and regular. Even Java written in Clojure is often more concise than Java written in Java thanks to macros like -> and doto, and constructs like proxy and (soon) reify.

  8. Java code has too much mandatory boilerplate and endless repetition. public static void main(String[] args){...} etc. Clojure has next to none of this boilerplate, while sacrificing little to nothing in terms of expressiveness or power. Even other statically typed languages today seem to be going the way of type inference. There's good reason you need a bulky Java-centric IDE to write and endlessly "refactor" Java code; writing it by hand would drive you insane and wear your fingers down to nubs.

  9. In Java everything is a class or interface, whether it should be or not, which is a cause of unnecessary complexity. There are many programs that have to be mangled beyond recognition to fit into an OOP style. Clojure lets you avoid this. A nice rant to this effect. Clojure focuses largely on verbs.

  10. Interactive programming via REPL is fun. Compile/run/debug cycles are not. Clojure still compiles to .class files if you want it; in the meantime you can sit in the middle of your code and tinker freely while it's running.

  11. Clojure's metadata and sane equality testing are enjoyable to work with. As are its auto-promotion of int to long to Bigint, native handling of rational numbers, and so on.

  12. Dynamic typing leads to shorter, more generic thus more reusable thus more powerful code than static typing. (This is a highly debatable point, obviously, so I put it last.)

The popularity of Scala and Groovy and JRuby and Jython and endless other JVM-languages-that-aren't-Java should be seen as a good indication that while the JVM is good, Java-the-language is unpleasant for many people.

Brian Carper
Your point #10 really doesn't have anything to do with either Java or Clojure. It's trait of the implementation, and really not even that, it's more a trait of the development environment. Eclipse, having started its life as a Smalltalk IDE, has had a Java REPL for a decade now, it's just well hidden. Mono has a C# REPL. There are C and C++ interpreters out there which have REPLs. F#, Scala, Haskell have REPLs. 100% agree on your other 11 points, though.
Jörg W Mittag
Cool, I've never seen a Java REPL. If they exist and are used, that's a good thing. In Clojure / other Lisps the REPL is pretty much the standard, so there's excellent tool and community support for that it. Interactive programming is pretty much the only way to do Clojure programming. It seems not to have caught on in a lot of other languages quite as much.
Brian Carper
Just checked, it's still there: http://help.eclipse.org/galileo/topic/org.eclipse.jdt.doc.user/concepts/cscrapbook.htm Not nearly as nice as it was back when Eclipse was still VisualAge Smalltalk, though.
Jörg W Mittag
A: 

Brian has summarized it really well. Here is something that really impressed me. (From the book Programming Clojure by Stuart Halloway)

Java code, from the Apache Commons:

public class StringUtils {
    public static boolean isBlank(String str) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if ((Character.isWhitespace(str.charAt(i)) == false)) {
                return false;
            }
        }
        return true;
    }
}

Here is a similar implementation in Clojure:

(defn blank? [s] (every? #(Character/isWhitespace %) s))
sankara