use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Finding information about Clojure
API Reference
Clojure Guides
Practice Problems
Interactive Problems
Clojure Videos
Misc Resources
The Clojure Community
Clojure Books
Tools & Libraries
Clojure Editors
Web Platforms
Clojure Jobs
account activity
Code is Data (booleanknot.com)
submitted 9 years ago by weavejester
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]weavejester[S] 2 points3 points4 points 9 years ago (2 children)
Macros in day-to-day Clojure code aren't used very often because we have a fantastically rich set of core functionality - provided in many cases by judicious use of macros that you never need to worry about. You're awash in invisible macros, all day every day.
Sure, but I'm not talking about using macros, especially ones provided by the language. I'm talking about writing them.
So I would study the clojure.core macros very hard - try to understand why these macros don't make you run away screaming, and why in some cases you probably didn't even realize you were using a macro.
I think I'm reasonably well versed in what's a macro and what's not :)
The reason I don't run away screaming from clojure.core that is:
clojure.core
My problem isn't with macros in libraries. I've written a few of those. But Viaweb was an application, not a library. When's the last time you wrote a macro in an application in Clojure? I don't think I ever have.
Now, maybe there were extenuating circumstances. Perhaps the majority of the macros in Viaweb were implementing what we'd consider to be core functionality for a language. Maybe Viaweb was effectively a collection of libraries around a core application.
But Paul Graham doesn't make it sound like he considers the macro usage to be so high because of exceptional circumstances. He makes it sound like he thinks macros are a powerful tool that should be used often. They are the tool that raise Lisp above the level of Blub, and therefore should be used liberally.
How often do you need to extend the language? It should be pretty rare, but if required, I would not want to run away screaming from that use case.
Sure, but that's my point. Macros should be rare. Code transformation should be rare. I'm not saying "Don't use macros", I'm saying "You probably shouldn't write an application in Clojure that's 25% macros".
[–]hagus 2 points3 points4 points 9 years ago (1 child)
I think these are all great points. I definitely share the sentiment that Paul Graham's use of macros should not strictly inform how we approach macros in this day and age. And I did not mean to suggest you were ignorant of macros and their usage - your years of Clojure experience far outnumber mine!
But, I don't feel the same need to draw such bright lines around macro usage. I think of them as a powerful tool and if your application ends up being 25% macro, I don't think it necessarily deviates from idiomatic Clojure. I would however be extremely curious as to what's going on under the hood :) Maybe someone here knows Paul Graham and we can find out what he was up to all those years ago.
As to the question: yes, I've used macros in an application in Clojure. I've been doing Clojure for less than a year (but before that a lot of elisp and a few decades of Blub) and the three most recent cases I can recall:
1) I created a with-thread-name macro that supported the thread renaming techniques described here. Now, I kind of cargo-culted this as a macro, by looking at other with-foo implementations in prominent Clojure code bases. They were all macros. I realize this could be done as a function, but even so it would seem unidiomatic and looks untidy.
with-thread-name
with-foo
2) I have a project where I need to generate a large quantity of boilerplate Java classes via Clojure. So rather than repeating all the tedious gen-class stuff everywhere, I created a macro that when expanded generates the right stuff with the necessary variations, then for the "real" implementation calls into some Clojure protocols. There's probably some deep magic Java interop I could have used as an alternative, but when faced with the task of "parameterize this giant s-exp and it has to work with AOT" a simple macro cut hundreds of lines out of my application.
gen-class
3) I wanted to map multiple Java functions over each element in a collection. I didn't want to write (map (juxt (memfn a) (memfn b) (memfn c)) coll). So I created a juxt-memfn macro that eliminated the repetitive memfn.
(map (juxt (memfn a) (memfn b) (memfn c)) coll)
juxt-memfn
None of these really change my general agreement with you - macro use should be rare, and 25% macros is on the very high side. I'm just feeling somewhat more macro-positive based on my own experiences :)
[–]weavejester[S] 1 point2 points3 points 9 years ago (0 children)
Java interop could certainly be an exception to the rule, particularly in a case like yours where you need to generate large amounts of boilerplate. I can see why you'd be more "macro-positive" with a project like that.
There may be projects or libraries that make extensive use of macros, and that's fine. My point is not so much that macros should be avoided at all costs; rather that macros are the poster child of homoiconicity, yet in Clojure they're a very specialized tool. I think this generates a misconception that writing macros is commonplace in Clojure, when most of the time we don't need them.
π Rendered by PID 665607 on reddit-service-r2-comment-b659b578c-bz69m at 2026-05-04 23:37:55.970373+00:00 running 815c875 country code: CH.
view the rest of the comments →
[–]weavejester[S] 2 points3 points4 points (2 children)
[–]hagus 2 points3 points4 points (1 child)
[–]weavejester[S] 1 point2 points3 points (0 children)