This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-10-10
Channels
- # announcements (3)
- # babashka (3)
- # beginners (83)
- # calva (1)
- # cider (19)
- # clojure (131)
- # clojure-austin (4)
- # clojure-dev (3)
- # clojure-europe (49)
- # clojure-greece (2)
- # clojure-italy (8)
- # clojure-losangeles (18)
- # clojure-nl (14)
- # clojure-poland (1)
- # clojure-uk (65)
- # clojurescript (28)
- # core-async (7)
- # core-logic (3)
- # cursive (2)
- # data-science (1)
- # datomic (98)
- # defnpodcast (1)
- # figwheel-main (6)
- # fulcro (95)
- # graphql (5)
- # hoplon (7)
- # kaocha (1)
- # lein-figwheel (6)
- # luminus (1)
- # nyc (1)
- # off-topic (21)
- # pedestal (1)
- # quil (8)
- # re-frame (15)
- # reagent (106)
- # reitit (15)
- # shadow-cljs (158)
- # sim-testing (1)
- # spacemacs (17)
- # sql (25)
day 2 of getting the soffits and fascias done on our roof. Hopefully when they are done the wall at the front of the house won't leak
is your house engulfed by scaffolding?
have they just got a ladder?
tho they have to go up reasonably high for the gable ends (the roof isn't pitched very steeply tho, so even then it isn't bad)
I've got some code where I need to take a number of sequences, do some mapping and filtering on them and then turn them into a map of results. Is dummy code example reasonable?
(transduce
,,, ; some more transforms
,,,, ; some reducing step function
(sequence ,,, s1 s2 s3))
transducers are really only set up to process single values so you have to figure out what a value is it might be easier to turn into a sequence of maps?
(transduce
(comp
(filter #(odd? (:seq1 %)))
(map :seq3)
(map str))
(completing string/join)
""
(sequence (map #(zipmap [:seq1 :seq2 :seq3] %&))
(range 10)
(seq "abcdejghiklmop")
[:one-banana :two-banana :three-banana :four :five-bananas :make-a-bunch]))
kinda thing?don't think sequence
is buying you anything there though;
might as well be
(map #(zipmap [:seq1 :seq2 :seq3] %&)
(range 10)
(seq "abcdejghiklmop")
[:one-banana :two-banana :three-banana :four :five-bananas :make-a-bunch])
that's always the problem with sequence; its unique selling point is when someone has passed you a transducer as a parameter
I think it might avoid chunking
if that's desirable
if you are desperate for perfomance then its worth considering reducibles
it sort of depends on the performance of your input data
@ben.hammond agreed. I think I'm trying to see if there are smaller changes I can make atm
(sotto voce) reducibles are quite easy
its just a loop/recur, sugared up to make it palatable for reduce
@ben.hammond where would be a good place to read up on that?
hmm, its not actually all that well described
hints at it
maybe its worth writing a blog post over
essentially you are reifying clojure.lang.IReduceInit
whilst worrying about respecting 'reduced' short circuits
so you can write something like
(defn iterator-reducible
"expresses an iterator through the medium of IReduceInit
if first-val is nil it will be ignored"
[first-val ^java.util.Iterator it]
(reify IReduceInit
(reduce [_ f start]
(loop [acc (if first-val
(f start first-val)
start)]
(if (or (reduced? acc)
(not (.hasNext it)))
(unreduced acc)
(recur (f acc (.next it))))))))
(which you can use to wrap any old java.util.Iterator
to make it amenable to reduce
or into
)
(wilfully ignoring iterator-seq
for now)
so you
- sit in a loop
- call (f acc v)
if you wish to pass the value to the outside world
- just skip that value if you dont
- alway check (reduced? acc)
; this covers you for the sort of short-circuit that is used by (take 2)
- just return acc
when you are done
essentially we are just doing
(loop [acc init]
(if (.hasNext it)
(recur (f acc (.next it)))
acc))
which can run with very low overheads
avoid consuming memory in multiple chunked sequences, etc
you can plug it into transduce/reduce/into
as though it were a collection
(transduce (filter even?) + 0 (iterator-reducible nil (.iterator (range 10))))
=> 20
(into [] (filter even?) (iterator-reducible nil (.iterator (range 10))))
you do have to worry about init value though
(reduce + 0 (iterator-reducible nil (.iterator (range 10))))
=> 45
(reduce + (iterator-reducible nil (.iterator (range 10))))
Execution error (ClassCastException) at dev/eval4729 (form-init9996294491577087656.clj:1).
dev$iterator_reducible$reify__4655 cannot be cast to clojure.lang.IReduce
you could reify clojure.lang.IReduce
of course
@otfrom this is the sort of thing I was talking about https://juxt.pro/blog/posts/ontheflycollections-with-reducible.html
oh it's a particularly shaggy dog
that was a subliminal angle I only just realised
your io code looks similar to this: https://github.com/cgrand/xforms/blob/master/src/net/cgrand/xforms/io.clj#L14-L34
oh I wasn't aware of that
once you get started writing these you find that they're useful all over the place
@otfrom this is the sort of thing I was talking about https://juxt.pro/blog/posts/ontheflycollections-with-reducible.html