Hi Palak! :-) We could talk for hours on the topics you raised, but hopefully I can give you answers sufficient to further whet your appetite for Clojure.
Clojure is a dynamically-typed programming language that, yes, targets the JVM. (It also has siblings that target
JavaScript,
.NET,
Python,
C (via scheme), and other languages and environments, but I'll only talk about Clojure proper, which is JVM-only.)
Clojure is also a lisp, which means that the language is defined in terms of its own data structures; this is the "code as data" concept you've heard of. This means that you can use Clojure to trivially read, write, manipulate, and generate Clojure code. This is the foundation for macros (a key feature of all lisps), and can be a huge boon in many domains where, if you didn't have Clojure, you might use much less flexible and powerful code generation tools (such as javacc, or Project Lombok, or really any annotation processor that generates classes, methods, or fields for you).
As far as when
you should use Clojure instead of, e.g. Java, my general answer is "always". ;-) I replied on this particular subject just now,
here.
Now, unless you head over to one of the other Clojure implementations, there are few places where you might choose it over C or C++. Clojure is not a systems programming language, so the overlap there is small. Clojure is intended for building applications, small to large to huge.
Choosing between Python and Clojure requires a little more thought, as Python is also quite concise and has a great library selection and community. However, Python suffers (along with Java) with a lack of proper functional programming (FP) facilities. As I said in
the other thread, once you go FP, you'll never go back. Programming using in-place mutation of state is a remarkably complicated way to solve problems; Clojure makes it easy to avoid such practices, and provides immutable data structures that make doing so efficient.
One thing we touch on in the book is that Python (and Ruby) are quite slow compared to Clojure on the JVM. This means that, if you appreciate the concision, productivity, and community offered by Python (or Ruby), but are frustrated by their performance, you will find yourself quite at home with Clojure. Like Python and Ruby, it places a premium on developer productivity, interactive development, and fostering a large, healthy, engaged community; but, Clojure (again, thanks to the JVM underneath) is many factors faster than both Ruby and Python for nearly all tasks (generally, anything that isn't e.g. grounded in a C extension in Python).
Clojure runs on the JVM by dynamically generating JVM bytecode corresponding to the Clojure functions you define. So, for this trivial function:
…the Clojure compiler produces the JVM bytecode to define a new class (which implements
Runnable,
Callable, and Clojure's own function interface,
IFn) that has a single
invoke method, the body of which calls the
reduce function (passing the
+ function and the provided collection of
numbers), and then calls the
/ function with the result of the first call, and the size of the collection of
numbers (as returned by the call to the
count function).
This is made possible by the fact that Clojure's compiler is always available; thus, Clojure code is
always compiled, never interpreted. In addition, because Clojure function calls simply boil down to direct JVM method invocations, Clojure code can be astonishingly fast — in many cases, as fast as the analogous Java code.
I hope this has been helpful. Of course, we talk about all of these topics (and much, much more) in
the book, if you are ready for more. ;-)
--
(coauthor of
Clojure Programming from O'Reilly; creator of
Clojure Atlas)