In Clojure, when should we use a monad instead of a macro and vice-versa?
I've been using Clojure for two years now and the only time I ever used monads was as an exercise to show that it could be done. I've never needed them for "real" code.
Monads are much more common in Haskell because:
- They are the idiomatic way of handling stateful computations. In Clojure, you typically handle state with managed references, so monads aren't needed nearly as much in Clojure.
- Likewise for IO: Clojure allows you to do IO directly without declaring it in your type, so you don't need the IO monad.
My suggestion would be to focus on standard functional programming in Clojure. Unless you see that you really need monads then I wouldn't invest too much time in trying to bring them in.
Macros are a slightly different issue: they are for compile-time code generation and extensions to the language syntax (which might include DSLs, although DSLs don't necessarily need macros). I use macros when both of the following are true:
- I want to extend the language syntax in a way that significantly improves my ability to address a particular problem domain.
- I can't get the same functionality with normal functions / function composition. Normal functions should be your first choice if possible: they are usually simpler to write and maintain.
P.S. If you are genuinely interested in monads for Clojure, here are two videos I personally found quite good:
- http://vimeo.com/20717301 (Brian Marick's excellent visual explanation of monads)
- http://www.infoq.com/presentations/Monads-Made-Easy
@khinsen and @mikera answered the question so well that it's hardly to make any additional comments yet I think they missed one point (or I couldn't find it in their comments).
In Clojure macros are a part of the language. Use them or not, but they are there. In fact, you will often have no choice but use them since they make your applications more idiomatic (that's a feature of professional use of any language). They let you preprocess data structures that make up the application. They are akin to other language constructs in the sense they are included regardless of your needs.
Unlike macros, monads are not a part of Clojure. They are built using the language's constructs, namely macros. They are not included at runtime unless you insist on them being there. To me monads are design patterns for composing computations, and therefore they're akin to other design patterns you may be familiar with. You use design patterns to develop modular and cohesive applications and be it monads or macros or any other language construct you should know they exists and work with them for your good.
As to your question, macros work before monads ever kick in. Macros work at compilation phase - they change data structures to other data structures. Monads are a design pattern to compose computations. That's the difference. In Clojure, monads are written using macros (to make their use easier), and therefore people tend to say what you can do with monads you could easily achieve with macros. That's true as it comes out of monads design in Clojure, but the same might be said about macros themselves. You don't need to write new ones most of the time, and the first rule of the macro club is to not write them at all, but still they're a part of the language and you should be very well aware of their applications.
See How do Clojure programmers use Macros? for more discussion about macros.
Monads and macros have nothing in common. They are used for solving different problems. In Clojure, the monad library uses macros quite extensively for implementing the syntactical "user interface" to monads. You may well use monads to implement some library's functionally and than add a layer of macros for the external interface.
As for "when would one use monads in Clojure", I see two use cases:
1) To implement stuff that makes sense in more than one monad, in order to do the job only once and "plug in" the monad later. Here is a nice illustration of this approach, though unfortunately (from a pedagogical point of view) for a rather non-trivial application: logic programming.
2) To implement a composition technique that can be formulated as a monad, in order to profit from the existing monad infrastructure.
Clojure has two built-in monads, "let" (identity monad) and "for" (sequence monad). Whenever you wish you could plug one of them into your code later on, you should use "domonad" instead. And whenever you wish you had something similar but not quite the same, you should consider writing your own monad.
This remains rather abstract, unfortunately. There aren't many published and polished code examples that use monads in Clojure at this moment. As more Clojurians get familiar with monads and more monad experts (usually coming from Haskell) use Clojure, this is likely to change. I have seen (but don't have at hand) monadic parsing done in Clojure, for example.