Last active
October 17, 2016 04:05
-
-
Save paultopia/f374a964038a91e4afdb52c9376d3a33 to your computer and use it in GitHub Desktop.
clojure[script] transducers: basic use
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; attempted translation of the basic parts of the clojure documentation page on transducers http://clojure.org/reference/transducers | |
;; into more comprehensible terms that don't require you to be as smart as Rich Hickey to understand. | |
;; transducers are a way to compose sequence functions with less than their normal arity into a combined transformation | |
;; which then gets applied more efficiently than just nesting calls to the transformation, using ->, etc. | |
;; In the below, xf is a transducer. The composition goes left to right, hence tests for oddness before testing for less-than-5ness | |
(def xf | |
(comp | |
(filter odd?) | |
(filter #(> 5 %)))) | |
;; to just apply the composed transformation to a collection, the easiest thing is to use the `into` idiom | |
(def example [1 2 3 4 5 6 7 8 9 10]) | |
(into [] xf example) | |
;; [1 3] | |
;; `transduce` is just like normal `reduce` but with the xf composed with the reducing function first. The docs are a little obscure | |
;; on what that means ("with the transducer xform applied to the reducing function f"---huh?) but it seems to mean composition in | |
;; that sense. | |
(transduce xf + example) | |
;; 4 | |
(transduce xf conj [] example) | |
;; [1 3] | |
;; I actually find this last one a bit magical. The docs say: | |
;; "f supplies the knowledge of how to accumulate the result, which occurs in the (potentially stateful) context of the reduce." | |
;; and what that seems to mean is "it somehow manages to act as if you applied the transducer to the whole collection before reducing." | |
;; `eduction` seems to basically just mean "create a lazy sequence from applying the transducer to the collection" | |
(take 2 (eduction xf example)) | |
;; (1 3) | |
;; for future reference, here's the list of the built-in higher-order sequence functions that make transducers with one less arity, | |
;; straight from the docs: | |
;; map cat mapcat filter remove take take-while take-nth drop drop-while replace partition-by partition-all keep keep-indexed | |
;; map-indexed distinct interpose dedupe random-sample | |
;; Christophe Grand has also written tranducerific support for more core functions at https://github.com/cgrand/xforms | |
;; right now they seem a little hard to understand (especially x/reduce!!) but reading the code is interesting... | |
;; this is a nice SO: http://stackoverflow.com/questions/26317325/can-someone-explain-clojure-transducers-to-me-in-simple-terms |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Typo on line 2: "comprensible" -> "comprehensible"