Daniel Compton

The personal blog of Daniel Compton - Projects

Peering into core.async buffers

Clojure’s core.async deliberately doesn’t expose a channel’s underlying buffer to the user. This is fine most of the time and encourages good practices and to use the library in an idiomatic way. However occasionally you do want to peer inside a channel. To get access to the buffer, call (.buf ch). Some interesting methods you might like to call on the buffer:

(.buf (.buf ch)) ;; Get elements in buffer
;; => (:chan :on :elements)

(.count (.buf ch)) ;; Get number of elements in buffer
;; => 3

(.n (.buf ch)) ;; Get size of buffer
;; => 10

(.full? (.buf mychan)) ;; Is buffer full?
;; => false

N.B. This is definitely not recommended for production usage. Accessing a channel’s buffer isn’t thread safe, and it breaks a lot of guarantees that core.async provides. However as an aid in debugging at development time it can be quite handy.

Update: Another method for doing this is to create your own transparent buffers that you can inspect.

Getting Clojure map entries

Sometimes when you’re working with Clojure maps you want to get both the key and the value together. To do this, use find. find returns a clojure.lang.MapEntry which looks and smells like a two element vector, and can be manipulated like one.

(find {:key :val} :key)
;; => [:key :val]

(type (find {:key :val} :key))
;; => clojure.lang.MapEntry