Over a million developers have joined DZone.

From Stateful Iteration in Python to Stateless Clojure

· Java Zone

Learn more about how the Java language, tools and frameworks have been the foundation of countless enterprise systems, brought to you in partnership with Salesforce.

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.

Discover how the Force.com Web Services Connector (WSC) is a code-generation tool and runtime library for use with Force.com Web services, brought to you in partnership with Salesforce.


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 }}