3 ms·
I've been programming in Clojure professionally for roughly ten years now. It's a great language and extremely effective if you're building products both on the
by d_t_w 5y ago
I've been programming in Clojure professionally for roughly ten years now. It's a great language and extremely effective if you're building products both on the JVM and in the browser.
I think I've written a handful of macros in that time, there is one in my current codebase in a test class, and it could probably be removed.
Macros are for extending the language. Programmers who are new to Clojure tend to pick macros up and get a bit excited and create lots of DSLs and other cute little trinkets, and then they put macros down again because they realise they don't compose.
The power of Clojure is in simple datastructures, the core functions that operate on them, composition, and host interop.
The most useful thing that I made with macros was a library for opinionated exception handling for Clojure core.async, at the end of which I realised I was using core.async a bit too much and ended up removing a bunch of it.
The product I work on today is an Enterprise toolkit for Apache Kafka (https://kpow.io https://kpow.io) that according to Github is 97% Clojure. Data-oriented, great delivery cadence, and terrific fun to work on. Having a single language on the JVM and in the Browser is enormous leverage, certainly we feel the benefit every day.
- eyelidlessness 5y agoIt’s been several years since I’ve worked in Clojure. When I started to dive into the language, I was warned not to write macros without a good justification (and heeded those warnings). One of my most memorable projects[1] relied heavily on macros. I knew at the time that I was using the tools I had to automate a performance optimization technique. What I didn’t know at the time was that my former (and once again future) ecosystem, JavaScript (now TypeScript), was going through a tooling revolution (of sorts, no value attached to that observation). Babel, and then countless other tools, were transforming more and more JS. Now that sort of thing is pretty much the default. All of that is to say: macros are not a silver bullet, they’re not trivial to write/read/maintain… but goodness dealing with similar use cases in JS environments routinely makes me long for them. The amount of esoteric knowledge required to build something similar to my 150 line library in a JS context is absolutely bonkers. Versus just using built in language features and calling runtime functionality as needed at build time. I don’t want to overly romanticize either macros generally or Clojure specifically. But I sincerely believe a large part of the frustration with the JS ecosystem from developers’ perspective would be significantly less frustrating if manipulating the language and sharing build/runtime logic were part of the language itself. 1: https://github.com/reup-distribution/espalier https://github.com/reup-distribution/espalier
- d_t_w 5y agoThanks for sharing - you've spotted the hole in my experience. I tend to lead more on the JVM and I have talented team-mates who drive the architecture on the JS side. I love being able to contribute both front and back end feature-wise but I don't have too much depth in understanding the bigger issues and advantages/drawbacks of Clojure (and macros) in JS land.
- filoeleven 5y ago> relied heavily on macros There is one macro defined in that library. It looks like it uses Garden’s “defstyles” macro as a key component as well. I don’t intend to contradict what you wrote by pointing this out; it was just funny to read “relied heavily on macros” only to find exactly one “defmacro” in the codebase! This further illustrates your point: macros are a great tool to have in your toolbox, and when it’s worth writing one, it can be VERY much worth writing one.
- eyelidlessness 5y agoThis is a good clarification! By “relied heavily” I meant that’s how its core functionality is implemented, not that there’s a large corpus of macro code.