Skip to content

Instantly share code, notes, and snippets.

@runexec
Last active August 16, 2017 22:11
Show Gist options
  • Select an option

  • Save runexec/06b56a9dbd15e43145b9 to your computer and use it in GitHub Desktop.

Select an option

Save runexec/06b56a9dbd15e43145b9 to your computer and use it in GitHub Desktop.

Revisions

  1. runexec revised this gist Sep 14, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion clojure-transduce-reduce.md
    Original file line number Diff line number Diff line change
    @@ -117,7 +117,7 @@ Notes and examples of Transducers and Reducers

    ```

    * For lazy transformations you must use ```clojure sequence```
    * For lazy transformations you must use ```sequence```

    ```clojure

  2. runexec revised this gist Sep 13, 2014. 1 changed file with 26 additions and 0 deletions.
    26 changes: 26 additions & 0 deletions clojure-transduce-reduce.md
    Original file line number Diff line number Diff line change
    @@ -117,3 +117,29 @@ Notes and examples of Transducers and Reducers

    ```

    * For lazy transformations you must use ```clojure sequence```

    ```clojure

    (def star-wrap
    (map #(str "*" % "*")))

    ;=> #'user/star-wrap

    (into [] star-wrap [1 2 3])

    ;=> ["*1*" "*2*" "*3*"]

    (sequence star-wrap [1 2 3])

    ;=> ("*1*" "*2*" "*3*")

    (type (into [] star-wrap [1 2 3]))

    ;=> clojure.lang.PersistentVector

    (type (sequence star-wrap [1 2 3]))

    ;=> clojure.lang.LazyTransformer

    ```
  3. runexec created this gist Sep 13, 2014.
    119 changes: 119 additions & 0 deletions clojure-transduce-reduce.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,119 @@
    ## Transducers and Reducers

    Notes and examples of Transducers and Reducers

    ### Reducers

    * Used on collections

    * Eager evaluation only. (not lazy)

    * The operation(s) and the input are no longer tied together

    ```clojure

    (r/map zero?)

    ;=> #<reducers$map$fn__2527 clojure.core.reducers$map$fn__2527@7201f000>

    (let [map-zero? (r/map zero?)
    inputs [0 1 0 1 0 1]]
    (reduce conj [] (map-zero? inputs)))

    ;=> [true false true false true false]

    ```
    * Can be combined into a single function for better performance. (composable)

    ```clojure

    (def zero?-and-not-false
    (comp
    (r/filter true?)
    (r/map zero?)))

    ;=> #'user/zero?-and-not-false

    (reduce conj [] (zero?-and-not-false [0 1 0 1 0 1]))

    [true true true]

    ```

    ### Transducers

    * Can be used in ClojureScript

    * Function C is the reducing function

    * Function B calls Function C

    * Function A creates Function B

    * (A C) -> B


    ```clojure

    (defn a [c]
    (fn b
    ([] (c))
    ([coll] (c coll))
    ([coll input] (c coll input))))

    ;=> #'user/a

    (transduce a + [1 2 3])

    ;=> 6

    ```

    * Doesn't care about the input type

    * Transducers seem to be faster than reducers

    ```clojure

    (dotimes [n 5] (time (r/reduce + 0 [1 2 3])))

    "Elapsed time: 0.23142 msecs"
    "Elapsed time: 0.047252 msecs"
    "Elapsed time: 0.043944 msecs"
    "Elapsed time: 0.062372 msecs"
    "Elapsed time: 0.05938 msecs"

    ;=> nil

    (dotimes [n 5] (time (transduce a + 0 [1 2 3])))

    "Elapsed time: 0.1257 msecs"
    "Elapsed time: 0.026548 msecs"
    "Elapsed time: 0.018166 msecs"
    "Elapsed time: 0.031276 msecs"
    "Elapsed time: 0.024773 msecs"

    ;=> nil
    ```

    * Collection fns of previous Clojure versions are now optionally Transducers

    ```clojure

    (let [*2 #(* % 2)
    *4 #(* % 4)]

    (def weird-composition
    (comp
    (filter even?)
    (map *2)
    (map *4))))

    ;=> #'user/weird-composition

    (into [] weird-composition [1 2 3 4])

    ;=> [16 32]

    ```