/funky-struct

Clojure Implementations of Purely Functional Data Structures

Primary LanguageClojureEclipse Public License 1.0EPL-1.0

funky-struct

This is an exploration of data structures from Chris Okasaki's Purely Functional Data Structures implemented in Clojure. The goal is to implement a subset of the data structures that are presented in the text.

Usage

Each data structure that has been selected conforms (more or less) both to the signature provided by Okasaki and a Clojure collection. The choice of Clojure collection depends on the data structure.

BatchedQueue

The BatchedQueue data structure implements the Queue signature as well conforms to the IPersistentList protocol. Some of these ideas come from Rich Hickey's PersistentQueue Java class in clojure.core, but this is implemented in pure Clojure. BatchedQueue consists of a list and a vector. Either can be nil but the vector must be nil if the list is nil. As with PersistentQueue, the vector does not have to be reversed but is converted into a list.

To create a BatchedQueue, it is best to start with the EMPTY queue:

(use 'funky-struct.queue.batched-queue)
;; -> nil
(def q EMPTY)
;; -> #'user/q
q
;; -> #batched-queue{:front nil :rear nil}

From there more data can be added, either by the .snoc method:

(-> EMPTY (.snoc :a) (.snoc :b) (.snoc :c))
;; -> #batched-queue{:front (:a) :rear [:b :c]}

or the cons method (used here by into):

(into EMPTY (range 5))
;; -> #batched-queue{:front (0) :rear [1 2 3 4]}

The heads and tails can be found in the Okasaki or Clojure style:

(def q (into EMPTY (range 5)))
;; -> #'user/q
(.head q)
;; -> 0
(peek q)
;; -> 0
(.tail q)
;; -> #batched-queue{:front (1 2 3 4) :rear nil}
(pop q)
;; -> #batched-queue{:front (1 2 3 4) :rear nil}

This structure is faster than a list or a vector for retrieving data in a first-in first-out scenario (aka, a queue).

TO-DO

Several more of Okasaki's data structures will be implemented.

License

Copyright © 2015 Andrew T. Flower

Distributed under the Eclipse Public License version 1.0.