• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Clojure Macros

 
Ari King
Greenhorn
Posts: 20
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 321
IntelliJ IDE Java Spring
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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).
 
Chas Emerick
author
Greenhorn
Posts: 27
Clojure
  • 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 290
9
Clojure Linux Mac OS X
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 20
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 290
9
Clojure Linux Mac OS X
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 27
Clojure
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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)
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic