Over a million developers have joined DZone.

From Stateful Iteration in Python to Stateless Clojure

DZone's Guide to

From Stateful Iteration in Python to Stateless Clojure

· Java Zone
Free Resource

Bitbucket is for the code that takes us to Mars, decodes the human genome, or drives your next car. What will your code do? Get started with Bitbucket today, it's free.

I have a piece of Python code that leverages a stateful object and was wondering how to reimplement it in the inherently stateless Clojure, without resorting to its facilities for managing state. It turns out to be simple and beautiful.

The core of the code is a for loop that transform a list of maps, while also using input from another iterator-like object, a Palette. The Palette has the method next() that remembers the last color used and returns the next one. Here it is:

class Palette:
    last_idx = 0
    colors = ["C04000", ...]
    def next(self):
        self.last_idx = (self.last_idx + 1) % len(self.colors)
        return self.colors[self.last_idx]
graph_items = []
for idx, item in enumerate(item_maps):
            "itemid": item['itemid'],
            "color": palette.next(),
            "sortorder": idx

In Clojure, we would rather have no such state (for reasons I won’t discuss now). However, when writing idiomatic Clojure, we actually don’t need to.

We will use the fact that map – the function that can transform collection items – can take not just one but any number of collections, iterating over all of them in parallel. Instead of using the stateful palette.next(), we will create an infinite sequence of (repeating) colors and pass it into map together with the items collection. We want also the index of the items so we pass in a third sequence, the range from 0 to infinity. The map function will be thus called with (the current index, the current item, the current color).

Using infinite sequences is quite common (and elegant) in Clojure.

This is what the code could look like:

;; An infinite sequence of the colors (starting
;; again with the 1st one, when all exhausted)
(def palette (cycle ["C04000" "..."]))
(defn make-graph-items [items]
   (fn [idx item color] {"itemid" (item "itemid"), "color" color, "sortorder" idx})
       (range) items palette))
(def graph-items (make-graph-items items))


Statelessness is not scary. It is fun.

Disclaimer: I am only learning both Python and Clojure.

Bitbucket is the Git solution for professional teams who code with a purpose, not just as a hobby. Get started today, it's free.


Published at DZone with permission of Jakub Holý, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}