Created
July 31, 2023 19:53
-
-
Save kawas44/c569be3284e9d2a9f2281230eb5171d9 to your computer and use it in GitHub Desktop.
Play with Clojure IReduceInit interface
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
(ns reducible | |
(:require [clojure.java.io :as io]) | |
(:import (clojure.lang IReduceInit))) | |
(defn file-lines | |
"Returns a reducible collection over lines of a file. | |
It is not lazy and releases resources when reduction ends." | |
[filepath] | |
(reify IReduceInit | |
(reduce [_this rf start] | |
(with-open [rdr (io/reader filepath)] | |
(loop [acc start] | |
(if (reduced? acc) | |
(unreduced acc) | |
(if-some [line (.readLine rdr)] | |
(recur (rf acc line)) | |
acc))))))) | |
(comment | |
(def lines (file-lines "tmp/lines.txt")) ;; returns a reified object | |
;;;; works with reduce ... sometimes :/ | |
(reduce conj [] lines) ;; returns lines | |
(reduce conj lines) ;; will fail on missing start value! | |
;; the contract of core/reduce is odd! | |
;;;; works with reducers/reduce | |
(require '[clojure.core.reducers :as r]) | |
(r/reduce conj lines) ;; returns lines | |
;; the contract of reducers/reduce is better! | |
;;;; works with anything that use `reduce` under the hood | |
(mapv identity lines) ;; mapv, filterv | |
(group-by first lines) | |
(set lines) | |
(into #{} lines) | |
(into [] (take 2) lines) ;; transducers | |
(run! prn lines) | |
;;;; works with reducers | |
(require '[clojure.string :as str]) | |
(def lines-upper (r/map str/upper-case lines)) ;; returns a reified object | |
(r/fold conj lines-upper) ;; returns lines to uppercase | |
;; | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment