Skip to content

Instantly share code, notes, and snippets.

@JulianBirch JulianBirch/
Last active Dec 24, 2015

What would you like to do?


A couple of macros that do useful, general things.


The easiest way to use Poppea in your project is via Clojars.


[net.colourcoding/poppea "0.0.1"]


  [poppea :refer :all])


document-partial does the same thing as partial, except that rather than returning a function, it returns a record that does the same thing and (importantly) is serializable.

(defn f [a b c d] (+ a b c d))

(document-partial f 1 2)
=> #poppea.DocumentedPartial{:-symbol user/f, :b 2, :a 1}

((document-partial f 1 2) 3 4)
=> 10

It's a proper data structure, so you can do things like this:

((assoc (document-partial f 1 2) :a 5) 3 4)
=> 14

Note that this provides a fairly elegant way of serializing anonymous functions: rewrite to a var function and then use document-partial.

Easter eggs

defrecord-get is the same as defrecord but implements acts as a function the same way a hash-map does. defrecord-fn is a helper function for records that implement IFn.


Poppea implements very basic ML-style currying in three closely related macros. defn-curried, defn-curried- and fn-curried

(defn-curried wrap-handler [handler request]
  (assoc (handler request) :x 3))

is the same as

(defn wrap-handler
  ([handler request]
   (assoc (handler request) :x 3))
   (fn [request] (assoc (handler request) :x 3))))

It should be pointed out that there are a couple of practical issues of which one should be aware when using defn-curried.

  • Since it's not returning a var, reloading on the repl won't change a curried function.
  • Be careful using currying with -> and ->>. The argument order may not be what you expect. Clojure doesn't have ML's rich operators.


defn-curried is marginally faster than partial. document-partial is significantly slower.

Road Map

I'd like to implement a version that does eager evaluation of the code that only depends on the curried arguments, but it's much more complex than what has currently been implemented.

It'd also be nice to have a generator macro, which rewrites imperative style code as a reducer. Turning a reducer into a lazy sequence shoudn't be problematic.


The other macro is coffee-map, which is inspired by Coffeescript's quick map syntax.

(let [x 3
      y 5]
  (coffee-map x y "a" 78))

is the same as

(hash-map :x 3 :y 5 "a" 78)

Basically, this is structuring, the complement of Clojures {:keys [x y]} destructuring.

Why is it called Poppea?



Copyright © 2013 Julian Birch

Distributed under the Eclipse Public License, the same as Clojure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.