Last active
November 20, 2021 00:06
-
-
Save ghadishayban/f905be564d1d37ba9fa4d77b0d5e8848 to your computer and use it in GitHub Desktop.
unified generators
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
;; | |
;; Example usages at the bottom of the file | |
;; | |
(defn productions | |
"Returns a sequence of values by repeatedly calling `produce!` until it | |
returns `fin`. The sequence can be used lazily/caching or reducible/non-caching. | |
The arity-2 variant's `produce!` takes no arguments and returns a value | |
or the terminator. | |
The arity-3 variant takes an initial state `s`, and its `produce!` function | |
takes the state and returns the next state or terminator. Each state will appear | |
in the sequence." | |
([produce! fin] | |
(reify | |
clojure.lang.Sequential | |
clojure.lang.Seqable | |
(seq [_] | |
((fn step-fn [] | |
(let [val (produce!)] | |
(if (identical? fin val) | |
nil | |
(cons val (lazy-seq (step-fn)))))))) | |
IReduceInit | |
(reduce [_ rf init] | |
(loop [res init] | |
(let [v (produce!)] | |
(if (identical? fin v) | |
res | |
(let [res (rf res v)] | |
(if (reduced? res) | |
@res | |
(recur res))))))))) | |
([s produce! fin] | |
(reify | |
clojure.lang.Sequential | |
clojure.lang.Seqable | |
(seq [_] | |
((fn step-fn [s] | |
(if (identical? fin s) | |
nil | |
(cons s (lazy-seq (step-fn (produce! s)))))) | |
s)) | |
clojure.lang.IReduceInit | |
(reduce [_ rf init] | |
(loop [acc init | |
s s] | |
(if (identical? fin s) | |
acc | |
(let [acc (rf acc s)] | |
(if (reduced? acc) | |
@acc | |
(recur acc (produce! s)))))))))) | |
;;;; two arity | |
;; (defn faster-line-seq | |
;; [^BufferedReader rdr] | |
;; (productions #(or (.readLine rdr) ::eos) ::eos)) | |
;;;; three-arity w/ internal state | |
;; user> (vec (productions 10 (fn [i] | |
;; (if (> i 5) (dec i) :fin)) :fin)) | |
;; [10 9 8 7 6 5] | |
;; this arity is useful for expressing things like paginating API calls |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
new version
Usage