If our Clojure implementation looked as above and performed this much worse than the optimal Java implementation there wouldn't be much point to Clojure for this specific use case. We could just implement the JavaBeans as Java classes and include them in our Clojure project.

Macros are perfect for eliminating the verbosity of gen-class . With an appropriate macro we only need to specify the name of the JavaBean, its fields, and their types. The macro will take care of generating all the required constructors, state, setters and getters.

We can also reduce the size and improve the performance of our JavaBeans by changing the way we deal with state. Instead of a single array of objects as the state, we'll use an object array where each element is an array of a primitive type, or an object. Non-primitive fields will be stored in the object array while primitive fields are stored in arrays of their primitive types.

The full WikipediaEditEvent has 13 fields, so it would be very tedious to write out all the required accessors. Using a macro it's easy, which brings us back to clj-bean and its (currently) sole purpose, the defbean macro. This is what the full definition of a Wikipedia edit event looks like:

( defbean WikipediaEditEvent [[ long timestamp ] [ String channel ] [ String title ] [ String diffUrl ] [ String user ] [ long byteDiff ] [ String summary ] [ boolean minor ] [ boolean new ] [ boolean unpatrolled ] [ boolean botEdit ] [ boolean special ] [ boolean talk ]])

You can find clj-bean on GitHub. There are good tutorials out there for learning how to write macros. If you are new to macros and want to understand clj-bean you may want to go through a macro tutorial and look at the tests before moving on to the implementation.

The beauty of macros is that you as a user of them only need to understand what they do, as explained in this post, and not necessarily how they do it with all the strange quoting rules and code generation under the hood - as long as they work without any issues, anyway.