aspose file tools*
The moose likes Clojure and the fly likes Clojure Macros Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Languages » Clojure
Bookmark "Clojure Macros " Watch "Clojure Macros " New topic
Author

Clojure Macros

Ari King
Greenhorn

Joined: Apr 22, 2010
Posts: 20
When is it best to use macros? From what I've seen macros are mostly used in DSL situations and it is (seemingly) generally recommended to use functions. Insights appreciated.
Palak Mathur
Ranch Hand

Joined: Jan 29, 2007
Posts: 313

Ari King wrote:When is it best to use macros? From what I've seen macros are mostly used in DSL situations and it is (seemingly) generally recommended to use functions. Insights appreciated.


Hi Ari,

Chan had given a reply here:

http://www.coderanch.com/t/586539/clojure/Clojure-Programming-Questions

See his last reply (second last post).


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

Joined: Jun 27, 2012
Posts: 27

95% of all of the programming you're likely to do in Clojure is going to be working with functions and data.

On the margins, you'll likely find some repetitive code or boilerplate that you'll want to eliminate from your main sources; in such circumstances, wrapping up that code into a macro that you can stuff off into an auxilary namespace will clarify the flow of the main narrative of your program. These macros aren't defining DSLs by any stretch — really, they're just straightforward code templates that happen to be part-and-parcel of the language itself.

Finally, there may be occasions where you really do want to introduce a particular notation (a.k.a. a DSL). And then, you will find the full power of macros to be a lifesaver. One thing I'd like to emphasize is that, the macros you build in this context should simply be sugar for core functionality implemented (and available!) as functions. Since one of the tradeoffs of macros that they cannot readily be composed as easily as functions, you always want to have your macros' functionality available via regular functions (perhaps at a lower level of abstraction if necessary).

All that said, you shouldn't avoid macros; rather, it's best to use them judiciously. For some other perspective on them, you might want to watch talks by Christophe Grand (one of my fine coauthors) and Michael Fogus.

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

Joined: Feb 09, 2011
Posts: 261
    
    5

To follow on from what Chas said, here's an example of a macro providing syntactic sugar, taken from my jsql library...

You can write a simple SQL query like this:

You might decide you want the entity names in the SQL to be quoted with back ticks (for MySQL, for example) so there's an option to the SQL-generating functions to provide a function that does quoting:

Because there are two SQL-generating functions - select and where - you have to provide the :entities argument to each. But the jsql library provide a macro to make this easier:

This macro walks over the code expression and where it finds calls to SQL-generating functions, it adds in the :entities option and quoting function, transforming the code (from the first example) into the code in the second example.

The macro doesn't add any new functionality, it just provides a shorthand way to use existing functionality which is a good use of a macro.
Ari King
Greenhorn

Joined: Apr 22, 2010
Posts: 20
Chas, thanks for the insight and various perspectives. It was very helpful.

Sean, thanks for the macro example. Do you also happen to have an example demonstrating Clojure's DSL capabilities via macros?
Sean Corfield
Ranch Hand

Joined: Feb 09, 2011
Posts: 261
    
    5

Ari King wrote:Sean, thanks for the macro example. Do you also happen to have an example demonstrating Clojure's DSL capabilities via macros?

Not off the top of my head. I haven't needed to do much with DSLs in Clojure yet so I haven't looked at anyone's code for that.
Chas Emerick
author
Greenhorn

Joined: Jun 27, 2012
Posts: 27

Ari King wrote:Chas, thanks for the insight and various perspectives. It was very helpful.

Sean, thanks for the macro example. Do you also happen to have an example demonstrating Clojure's DSL capabilities via macros?


Korma and Enlive are two libraries that provide what can be described as DSLs. Of course, that being the case, neither library's source is particularly small or easy to understand. Though, if you do the work to understand either (Enlive is particularly well-constructed IMO; I've not browsed around Korma's source enough to say either way), you'll be the better for it.

--
(coauthor of Clojure Programming from O'Reilly; creator of Clojure Atlas)
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Clojure Macros