This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes Clojure and the fly likes Clojure Programming - Few Questions Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Languages » Clojure
Bookmark "Clojure Programming - Few Questions" Watch "Clojure Programming - Few Questions" New topic
Author

Clojure Programming - Few Questions

Palak Mathur
Ranch Hand

Joined: Jan 29, 2007
Posts: 313

Hi,

Welcome authors of the book. I have few questions. But before that I will give you my background. I am a Java programmer and have done some coding in C, C++, Python. A few days back, I was trying to learn Clojure and had even put a Clojure sticker on CodeRanch. However, after few sessions of learning Clojure, I was not able to grasp its essence. My few questions, they might have been answered somewhere, but I want to know it from horses' mouth. The questions are:-

1. What is Clojure? Why should I consider using Clojure and not the languages that I have already used?
2. When should I be using Clojure and not C,C++, Python or Java? Some situations where you had preferred using Clojure would be a great help.
3. While reading Clojure documentation, one learns that it runs on JVM. How?
4. I also read about "code as data" thing. What does this means? Few examples will be great.

I think I will stop with these 4 questions (4 being my lucky number ).


Palak Mathur | My Blog | TechJaunt | What is JavaRanch? | List of All FAQs
Chas Emerick
author
Greenhorn

Joined: Jun 27, 2012
Posts: 27

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)
Palak Mathur
Ranch Hand

Joined: Jan 29, 2007
Posts: 313

Hi Chas,

Read your reply on other thread as well. Thanks for the answers. Yes, I am willing to learn Clojure and I am keen toward the same.

One question that comes to my mind is how to change your thought process to grasp functional programming and code as data concepts for programming. How should one approach a problem. Right now, I think about problems in terms of objects. How to change this thought to be inline with Clojure or FP?
Chas Emerick
author
Greenhorn

Joined: Jun 27, 2012
Posts: 27

Homoiconicity (a.k.a. "code as data") is a simple concept: code in a homoiconic language like Clojure is represented using the language's own data structures. This characteristic is hardly exclusive to lisps: TCL and XSLT are two other well-known homoiconic languages. The benefit of homoiconicity is that you can trivially write programs that write programs; doing this in a non-homoiconic language (like Java, or Python, or Perl) is often incredibly difficult, and usually devolves into error-prone and difficult-to-compose string manipulation and templating. Once you can marry a compiler with a homoiconic language, you can write macros, which you can think of as offering a massive superset of the functionality provided by Java's annotation processors: a macro can generate, transform, or process any code you want it to, based on its arguments, local environment, or other parameters, all prior to the compiler doing its work. The result is a mechanism that can be used to implement syntactic and semantic abstractions (a.k.a. language extensions) that are simply impossible without macros.

The practical difference between object-oriented programming and functional programming ends up being smaller than most people think. Generally speaking, classes define bags of mutable locations that are associated with methods that modify and provide access to the data held in those locations. Consider a typical Java class definition:



This class is essentially modeling a map of four named integer values. Clojure's approach to working with data is to simply let the data rest in its "natural" state; so, here's a "box" value in Clojure, as a map:



Clojure data structures are immutable, so there is no way to change the value of :x in that map. Instead, you would use Clojure's assoc function to produce a new map that contains the value of :x that you want, e.g.:



Now, functional programming emphasizes the use of "pure functions", where side effects (e.g. mutating the value of a storage location in-place) are prohibited, and functions always return the same result given a set of arguments. So, the map passed into assoc has not been modified, and the map that it returns can itself be used as the basis for later map values.

A great deal of work can be done in Clojure simply using its immutable data structures and its large standard library of pure functions. Later on, you can dig into using constructs like defrecord and deftype in order to define named types (which compile down to regular Java classes, and which have better performance characteristics than regular maps). But, this transition can be made on-demand and as necessary, generally without changing existing code, as e.g. defrecord instances participate in Clojure's core map abstraction, so functions like assoc, dissoc, and so on that work with maps will continue to work with records.

Explaining further would result in me re-writing the book, so I'll leave it at that. :-) I hope that taste of the practical side of object orientation vs. functional programming is illuminating.

All that said, homoiconicity and macros, while hugely powerful tools that you should come to understand and use as you move along on the Clojure path, aren't things that you need to understand deeply before being productive. On the other hand, functional programming is central to applying Clojure effectively. We definitely talk about both subjects in the book, but functional programming is given proportionally more "airtime".

--
(coauthor of Clojure Programming from O'Reilly; creator of Clojure Atlas)
Palak Mathur
Ranch Hand

Joined: Jan 29, 2007
Posts: 313

Thank you for you answers Chan. My interest in Clojure has increased 100x of the time when I started learning the language. I am currently studying the following tutorial: http://java.ociweb.com/mark/clojure/article.html.
Hope to get your books and get going!!
Palak Mathur
Ranch Hand

Joined: Jan 29, 2007
Posts: 313

Chas/Sean,

My current job includes creating integration solutions for our client using ESB concept. We are using proprietary products from a company. We are planning to do away with the products as license is coming to an end and develop our own solution. We had something like Spring Integration framework in mind. Does Clojure has any library that we can consider? We are currently analyzing the current libraries/framework that can support this thing.
Chas Emerick
author
Greenhorn

Joined: Jun 27, 2012
Posts: 27

Palak Mathur wrote:Chas/Sean,

My current job includes creating integration solutions for our client using ESB concept. We are using proprietary products from a company. We are planning to do away with the products as license is coming to an end and develop our own solution. We had something like Spring Integration framework in mind. Does Clojure has any library that we can consider? We are currently analyzing the current libraries/framework that can support this thing.


You can certainly use Clojure in a Spring (or JEE 6 or similar) application, if that's the underlying architecture you plan on pursuing.

There isn't a Clojure analogue of Spring, largely because the dependency injection (DI) pattern that underlies Spring is fundamentally boilerplate that exists to work around limitations in Java. In the 'Design Patterns' chapter, we talk some about achieving the same objectives as DI in Clojure, but without the complexities of managed beans, containers, and so on.

--
(coauthor of Clojure Programming from O'Reilly; creator of Clojure Atlas)
Palak Mathur
Ranch Hand

Joined: Jan 29, 2007
Posts: 313

Thank you Chas for being around. I was going through the table of content of the book and found some section referring to Middleware. What do you cover in that section?
Sean Corfield
Ranch Hand

Joined: Feb 09, 2011
Posts: 252
    
    5

Since Chas didn't respond, I figured I'd look it up in the book and report back...

The Middleware section is part of the overall Clojure and the Web chapter and refers specifically to middleware in the Ring web framework, which is the name given to plugins for Ring:
Clojure Programming, page 534 wrote:Middleware is any enhancement or modification of the effect of handlers. Remember that, because Ring requests and responses are Clojure maps, they can be transformed readily, and since handlers are just functions, it is trivial to produce composites of different functions to yield aggregate behavior. This typically manifests in middleware as a higher-order function that accepts one or more handlers (maybe with some configuration), which returns a new handler with whatever composite functionality is desired.

Ring middleware includes functions to add session and cookie handling, automatic reloading of code during development, file handling, multipart form support and so on. It's the standard way to add general functionality to a Ring application (essentially using AOP at runtime).
 
 
subject: Clojure Programming - Few Questions
 
Similar Threads
Python
The Future Is Visual Basic!
* Welcome Amit Rathore
Joy of Clojure - Questions
Benefits of Learning Clojure?