Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any example in which Clojure really shines against Java which is not concurrency/immutability-feature related?

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 ?
like image 837
user855 Avatar asked Dec 08 '09 03:12

user855


People also ask

What is clojure good for?

Clojure is being used extensively for processing large volumes of data. It is very well suited to data mining/commercial-AI (ie: Runa) and large scale predictions (aka WeatherBill). Clojure's concurrency story really helps in these data heavy domains where parallel processing is simply the only answer.

What is clojure based on?

Clojure runs on the Java platform and as a result, integrates with Java and fully supports calling Java code from Clojure, and Clojure code can be called from Java, too. The community uses tools like Leiningen for project automation, providing support for Maven integration.

Is clojure a proper Lisp?

Clojure is a member of the Lisp family of languages. Many of the features of Lisp have made it into other languages, but Lisp's approach to code-as-data and its macro system still set it apart.

What is clojure language?

Clojure is a dialect of Lisp, and shares with Lisp the code-as-data philosophy and a powerful macro system. Clojure is predominantly a functional programming language, and features a rich set of immutable, persistent data structures.


2 Answers

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 clamoring 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...) has 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.

like image 92
Brian Carper Avatar answered Oct 04 '22 04:10

Brian Carper


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))
like image 32
sankara Avatar answered Oct 04 '22 03:10

sankara