I found an interesting library in Haskell called Scrap Your Boilerplate based on a paper by Simon Peyton Jones which seems like an effective way to write code that can update large, deeply nested data structures in a functional programming language. It enables code like:
incS :: Float -> Salary -> Salary
incS k (S s) = S (s * (1+k))
increase :: Float -> Company -> Company
increase k = everywhere (mkT (incS k))
Which effectively increases the salary by a fixed proportion k for everyone in a potentially large and complex Company data structure.
Is there an equivalent library or approach to achieve the same kind of programming style in Clojure?
For example, how could I write the Clojure equivalent of the example used above:
(defn increase [company k]
(everywhere-in company (transform-map-values :salary #(* % (+ 1 k))))
The closest to this in Clojure is probably the "in" functions (assoc-in, update-in, dissoc-in).
These functions allow you to do deeply nested, pinpoint changes in clojure. There is no equivalent to these functions in Haskell because they rely heavily on dynamic typing.
They weren't around when this question was first asked, but I believe transducers enable a similar style of programming. Basically transducible processes implement a certain set of functions, which transducers can use to traverse over any transducible process.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With