-
-
Save ghadishayban/a24a3b2f77d2b5ae53a43d7f114555ba to your computer and use it in GitHub Desktop.
into
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
;; clojure.core/into | |
;; into passes conj! to transduce, then tries to complete the return on the _outside_ of transduce | |
;; halt-when overrides return of transduce with a persistent vector | |
(defn into | |
"Returns a new coll consisting of to-coll with all of the items of | |
from-coll conjoined. A transducer may be supplied." | |
;; elided | |
([to xform from] | |
(if (instance? clojure.lang.IEditableCollection to) | |
(with-meta (persistent! (transduce xform conj! (transient to) from)) (meta to)) ;; persistent! is really a rf completion | |
(transduce xform conj to from)))) | |
user=> (into [] (halt-when #{:anomaly} vector) [1 2 :anomaly 3 4]) | |
Execution error (ClassCastException) at user/eval1 (REPL:1). | |
class clojure.lang.PersistentVector cannot be cast to class clojure.lang.ITransientCollection | |
;; instead, add a completion arity to the reducing fn which that calls persistent! and reattaches meta | |
(defn into | |
[to xform from] | |
(let [rf (if (instance? clojure.lang.IEditableCollection to) | |
(fn | |
([] (transient to)) | |
([tcoll] (with-meta (persistent! tcoll) (meta to))) | |
([tcoll item] (conj! tcoll item))) | |
(fn | |
([] to) | |
([coll] coll) | |
([coll item] (conj coll item))))] | |
(transduce xform rf from))) | |
;; look ma, now halt-when can receive a completed persistent value, not a transient | |
user=> (into [] (halt-when #{:anomaly} vector) [1 2 :anomaly 3 4]) | |
[[1 2] :anomaly] | |
user=> (into [] (comp (halt-when #{:anomaly} vector) (map str)) [1 2 :anomaly 3 4]) | |
[["1" "2"] :anomaly] | |
;; this also means that halt-when can return a differently shaped thing from into's 'to' argument | |
;; which can make sense when processing anomalies | |
user=> (into [] (halt-when :anomaly #(assoc %2 :partial-results %1)) [1 2 {:anomaly :oh-no!} 3 4]) | |
{:anomaly :oh-no!, :partial-results [1 2]} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment