Created
November 13, 2015 18:03
-
-
Save skatenerd/91a6566713c856a13543 to your computer and use it in GitHub Desktop.
interactively understanding transducers
This file contains hidden or 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
user=> (def increment-a-list (map inc)) | |
#'user/increment-a-list | |
;I have partially-applied "map". It didn't blow up with an arity error. Success! | |
;Let's use it | |
user=> (increment-a-list [1,2,3]) | |
#object[clojure.core$map$fn__4549$fn__4550 0x7ebed7f2 "clojure.core$map$fn__4549$fn__4550@7ebed7f2"] | |
;not helpful. it looks like I called a function. What did I call? | |
user=> (type increment-a-list) | |
clojure.core$map$fn__4549 | |
;not helpful. what about the type of the garbage output? | |
user=> (type (increment-a-list [1,2,3])) | |
clojure.core$map$fn__4549$fn__4550 | |
;not helpful. Though, I do know this is a transducer, whatever that means. | |
;Transducers can transduce, so let's go for it | |
user=> (transduce increment-a-list [1,2,3]) | |
ArityException Wrong number of args (2) passed to: core/transduce clojure.lang.AFn.throwArity (AFn.java:429) | |
;my bad. it needs a "reducer" function | |
user=> (transduce increment-a-list + [1,2,3]) | |
9 | |
;aw sweet! [1,2,3] became [2,3,4] which in turn became (2+3+4) which is 9!!! | |
;let's level up. time to crush it. lemme implement a "last thing wins" reducer. | |
;here goes! | |
user=> (transduce increment-a-list (fn [a b] b) [1,2,3]) | |
ArityException Wrong number of args (0) passed to: user/eval1217/fn--1218 clojure.lang.AFn.throwArity (AFn.java:429) | |
; yo what? | |
; it needs to be able to take 0 arguments, but presumably also 2 arguments | |
user=> (defn takes-zero-or-two | |
#_=> ([a b] b) | |
#_=> ([] 0)) | |
#'user/takes-zero-or-two | |
;ok, got my new reducer. let's go | |
user=> (transduce increment-a-list takes-zero-or-two [1,2,3]) | |
ArityException Wrong number of args (1) passed to: user/takes-zero-or-two clojure.lang.AFn.throwArity (AFn.java:429) | |
;this game is fun! add a third signature! | |
user=> (defn has-many-signatures | |
#_=> ([] 0) ([a] a) ([a b] b)) | |
#'user/has-many-signatures | |
user=> (transduce increment-a-list has-many-signatures [1,2,3]) | |
4 | |
;booyah. last-one-wins, except the last-one came from the incremented list, so it's 4 and not 3! | |
;what about a 'first-guy-wins'? | |
user=> (defn leave-bucket-alone | |
#_=> ([] 0) ([a] a) ([a b] a)) | |
#'user/leave-bucket-alone | |
user=> (transduce increment-a-list leave-bucket-alone [1,2,3]) | |
0 | |
;i guess that is expected. we call the reducer with zero-arity to get the seed, then we are using the 2-arity version. | |
;what's the point of the 1-arity version? | |
user=> (defn weird-handoff | |
#_=> ([] 1) ([a] (inc a)) ([a b] a)) | |
#'user/weird-handoff | |
user=> (transduce increment-a-list weird-handoff [1,2,3]) | |
2 | |
;oh, so we call the 0-arity version, and then we put that value into the 1-arity version, | |
;and then, after _that_, we start using the 2-arity reduce the way reduce normally works. | |
;got it |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment