Skip to content

Commit

Permalink
Correct reduction without an init value.
Browse files Browse the repository at this point in the history
  • Loading branch information
pjstadig committed Aug 22, 2016
1 parent 0b60874 commit d0f0827
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 7 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file. This change
log follows the conventions of [keepachangelog.com](http://keepachangelog.com/).

## [Unreleased]
### Fixed
- Correctly implement reduce semantics for reductions without an init value.

## [0.1.1] - 2016-08-18
### Fixed
Expand Down
16 changes: 15 additions & 1 deletion src/pjstadig/reducible_stream.clj
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,21 @@
(reify
clojure.lang.IReduce
(reduce [this f]
(.reduce this f (f)))
(io!
(with-open [stream (io/input-stream stream)]
(let [stream (cond-> stream
open (open))]
(try
(let [decoded (->> (repeatedly #(decoder stream ::eof))
(take-while (complement #{::eof})))]
(if (seq decoded)
(reduce f (first decoded) (rest decoded))
(f)))
(finally
(if close
(close stream)
(if (instance? Closeable stream)
(.close ^Closeable stream)))))))))
clojure.lang.IReduceInit
(reduce [this f init]
(io!
Expand Down
21 changes: 15 additions & 6 deletions test/pjstadig/reducible_stream_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,27 @@
(lines-decoder stream eof))
close (fn [stream]
(swap! calls conj :close))
result (->> (lines-stream "UTF-8" "blah" "blah" "blah")
result (->> (lines-stream "UTF-8" "first" "second" "third")
(decode! decoder {:open open :close close})
(into [] (take 1)))]
(is (= 1 (count result))
"should return only one item")
(is (= [:open :decoder :close] @calls)
"should consume only one item"))
(is (= "blahblahblah"
(reduce str
(->> (lines-stream "UTF-8" "blah" "blah" "blah")
(is (= "firstsecondthird"
(reduce (fn
([] "no-arg")
([a b] (str a b)))
(->> (lines-stream "UTF-8" "first" "second" "third")
(decode! lines-decoder {:open lines-open}))))
"should work when init is not provided"))
"should take first item when init is not provided")
(is (= "no-arg"
(reduce (fn
([] "no-arg")
([a b] (str a b)))
(->> (lines-stream "UTF-8")
(decode! lines-decoder {:open lines-open}))))
"should call no-arg reducer when collection is empty"))

(deftest t-decode!-as-seq
(let [calls (atom [])
Expand All @@ -43,7 +52,7 @@
(lines-decoder stream eof))
close (fn [stream]
(swap! calls conj :close))
result (->> (lines-stream "UTF-8" "blah" "blah" "blah")
result (->> (lines-stream "UTF-8" "first" "second" "third")
(decode! decoder {:open open :close close})
(take 1))]
(is (= 1 (count result))
Expand Down

0 comments on commit d0f0827

Please sign in to comment.