Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure equivalent of Haskell's "Scrap Your Boilerplate" (SYB)

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))))
like image 643
mikera Avatar asked Sep 11 '11 05:09

mikera


2 Answers

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.

like image 102
Conrad Barski Avatar answered Sep 23 '22 01:09

Conrad Barski


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.

like image 23
Karl Bielefeldt Avatar answered Sep 21 '22 01:09

Karl Bielefeldt