I was experimenting with some sequences today, and ran into a stumbling block: Using immutable data structures, how do you execute multiple transformations in series on an object, and return the final value?
For instance, consider a sequence of numbers,
user> (range 90 100) (90 91 92 93 94 95 96 97 98 99)
How do you transform them such that you increment each number by 1, and then get their text representation,
Imperatively speaking, you would run a loop on each word, and transform the sequence data structure in place, and the last operation would achieve the desired result. Something like,
>>> s = "" >>> a = [i for i in range(90,100)] >>> a [90, 91, 92, 93, 94, 95, 96, 97, 98, 99] >>> for i in range(0,len(a)): ... s += chr(a[i]+1) ... >>> s '[\\]^_`abcd'
If you knew about maps in python, this could be achieved with something like,
>>> ''.join([chr(i+1) for i in range(90,100)]) '[\\]^_`abcd'
The easiest way to do this in Clojure is using the excellently named Thrush operator (-> and ->>). According the doc,
Threads the expr through the forms. Inserts x as the
second item in the first form, making a list of it if it is not a
list already. If there are more forms, inserts the first form as the
second item in second form, etc.
It is used like this,
user> (->> (range 90 100) (map inc) (map char) (apply str)) "[\\]^_`abcd"
Basically, the line, (-> 7 (- 3) (- 6)) implies that 7 be substituted as the first argument to -, to become (- 7 3). This result is then substituted as the first argument to the second -, to get (- 4 6), which returns -2.
user> (-> 7 (- 3) (- 6)) -2