Stack implementation in Clojure II - A functional approach

My last post on the topic was creating a stack implementation using Clojure protocols and records – except, it used atoms internally and wasn’t inherently “functional”.

Here’s my take on a new implementation that builds on the existing protocol and internally, always returns a new stack keeping the original one unmodified. Comments welcome!

(ns viksit-stack (:refer-clojure :exclude )) (defprotocol PStack "A stack protocol" (push "Push element in") (pop "Pop element from stack") (top "Get top element from stack")) ; A functional stack record that uses immutable semantics ; It returns a copy of the datastructure while ensuring the original ; is not affected. (defrecord FStack PStack (push "Return the stack with the new element inserted" (FStack. (conj coll val))) (pop "Return the stack without the top element" (FStack. (rest coll))) (top "Return the top value of the stack" (first coll))) ; The funtional stack can be used in conjunction with a ref or atom viksit-stack> (def s2 (atom (FStack. '()))) #'viksit-stack/s2 viksit-stack> s2 #<atom> viksit-stack> (swap! s2 push 10) #:viksit-stack.FStack{:coll (10)} viksit-stack> (swap! s2 push 20) #:viksit-stack.FStack{:coll (20 10)} viksit-stack> (swap! s2 pop) #:viksit-stack.FStack{:coll (10)} viksit-stack> (top @s2) 10 </atom>

--

If you have any questions or thoughts, don't hesitate to reach out. You can find me as @viksit on Twitter.