Public Vars

Back

transduce (clj)

(source)

function

(transduce xform f coll) (transduce xform f init coll)
reduce with a transformation of f (xf). If init is not supplied, (f) will be called to produce it. f should be a reducing step function that accepts both 1 and 2 arguments, if it accepts only 2 you can add the arity-1 with 'completing'. Returns the result of applying (the transformed) xf to init and the first item in coll, then applying xf to that result and the 2nd item, etc. If coll contains no items, returns init and f is not called. Note that certain transforms may inject or skip items.

Examples

clojure/core.typed
(ns ^:skip-wiki clojure.core.typed.ann.clojure
  "Type annotations for the base Clojure distribution."
  (:require [#?(:clj clojure.core.typed
                :cljs cljs.core.typed)
             :refer [defalias] :as t]))

(defalias
  ^{:doc "A transducer function that transforms in to out."
    :forms '[(Transducer in out)]}
  t/Transducer
  (t/TFn [[in :variance :contravariant]
          [out :variance :covariant]]
         (t/All [r]
                [(t/Reducer out r) :-> (t/Reducer in r)])))
typedclojure/typedclojure
(ns ^:no-doc typed.ann.clojure
  "Type annotations for the base Clojure distribution."
  #?(:cljs (:require-macros [typed.ann-macros.clojure :as macros]))
  (:require [clojure.core :as cc]
            [typed.clojure :as t]
            #?(:clj [typed.ann-macros.clojure :as macros])
            #?(:clj typed.ann.clojure.jvm) ;; jvm annotations
            #?(:clj clojure.core.typed))
  #?(:clj
     (:import (clojure.lang PersistentHashSet PersistentList
                            APersistentMap #_IPersistentCollection
                            #_ITransientSet
                            IRef)
              (java.util Comparator Collection))))

(t/defalias
  ^{:doc "A transducer function that transforms in to out."
    :forms '[(Transducer in out)]}
  t/Transducer
  (t/TFn [[in :variance :contravariant]
          [out :variance :covariant]]
         ;; note: putting t/Transducer in an IFn makes r existential (but only in contravariant position IIUC? need to revisit my notes)
         ;; Stephen Dolan noted this when I showed him the type of `into`.
         ;; eg., Simulating Existential Types https://www.cs.cmu.edu/~fp/courses/15312-f04/assignments/asst5.pdf
         (t/All [r]
                [(t/Reducer out r) :-> (t/Reducer in r)])))

cc/reduce (t/All [a c] (t/IFn 
                         ;Without accumulator
                         ; default
                         ; (reduce + my-coll)
                         [[a a :-> (t/U (t/Reduced a) a)] (t/NonEmptySeqable a) :-> a]
                         [(t/IFn [a a :-> (t/U (t/Reduced a) a)] [:-> a]) (t/Seqable a) :-> a]
                         ; default
                         ; (reduce + 3 my-coll)
                         ; (reduce (fn [a b] a) (reduced 1) nil) 
                         ; ;=> (reduced 1)
                         [[a c :-> (t/U (t/Reduced a) a)] a (t/Seqable c) :-> a]))
cc/transduce (t/All [a b c] (t/IFn [(t/Transducer a a) (t/Reducer a a) (t/Seqable a) :-> a]
                                   [(t/Transducer b c) (t/IFn [c :-> c] [c a :-> (t/U c (t/Reduced c))]) a (t/Seqable b) :-> a]))
cc/reduce-kv (t/All [a k v] [[a k v :-> (t/U (t/Reduced a) a)] a (t/Option (t/Associative k v)) :-> a])
cc/reductions (t/All [a b] (t/IFn [[a a :-> (t/U (t/Reduced a) a)] (t/NonEmptySeqable a) :-> (t/NonEmptyASeq a)]
                                  [(t/IFn [:-> a] [a a :-> (t/U (t/Reduced a) a)]) (t/Seqable a) :-> (t/NonEmptyASeq a)]
                                  [[a b :-> (t/U (t/Reduced a) a)] a (t/Seqable b) :-> (t/NonEmptyASeq a)]))
cc/reduced (t/All [x] [x :-> (t/Reduced x)])
cc/unreduced (t/All [x] (t/IFn [(t/Reduced x) :-> x]
                               [(t/U x (t/Reduced x)) :-> x]))
cc/ensure-reduced (t/All [x] [(t/U x (t/Reduced x)) :-> (t/Reduced x)])
cc/completing (t/All [a b] [(t/IFn [:-> b] [b a :-> (t/U b (t/Reduced b))])
                            [b :-> b]
                            :-> (t/Reducer a b)])

cc/into
(t/All [x y :named [a]]
       (t/IFn [(t/Map x y) (t/Seqable (t/MapConjable x y)) :-> (t/Map x y)]
              [(t/Vec x) (t/Seqable x) :-> (t/Vec x)]
              [(t/Set x) (t/Seqable x) :-> (t/Set x)]
              ;unsound. t/Coll would need an extra param to specify Conjable elements.
              [(t/Coll t/Any) t/AnySeqable :-> (t/Coll t/Any)]
              ; transducer arities
              [(t/Map x y) (t/Transducer a (t/MapConjable x y)) (t/Seqable a) :-> (t/Map x y)]
              [(t/Vec x) (t/Transducer y x) (t/Seqable y) :-> (t/Vec x)]
              [(t/Set x) (t/Transducer y x) (t/Seqable y) :-> (t/Set x)]
              ;unsound. t/Coll would need an extra param to specify Conjable elements.
              [(t/Coll t/Any) (t/Transducer y t/Any) (t/Seqable y) :-> (t/Coll t/Any)]))
typedclojure/typedclojure
(ns clojure.core.typed.test.symbolic-closures
  (:require
    [typed.clojure :as t]
    [typed.clj.checker.test-utils :refer [is-tc-e is-tc-err tc-e is-tc-err-messages]]
    [typed.clj.checker.parse-unparse :refer [parse-clj]]
    [clojure.core.typed.util-vars :as vs]
    [typed.cljc.checker.type-rep :as r]
    [clojure.test :refer [deftest is]]))

(deftest transducer-symb
  (is-tc-e (map #(do %)))
  (is-tc-e (map identity))
  (is-tc-e (map identity)
           (t/Transducer t/Int t/Int))
  (is-tc-err (map identity)
             (t/Transducer t/Int t/Bool))
  (is-tc-e (map identity)
           (t/Transducer t/Int (t/U t/Bool t/Int)))
  (is-tc-e (map #(t/ann-form % t/Int)))
  (is-tc-e (map #(t/ann-form % t/Nothing)))
  (is-tc-e (map #(inc %)))
  (is-tc-e (map #(inc %)) (t/Transducer t/Int t/Int))
  (is-tc-e (map #(inc (t/ann-form % t/Int))) (t/Transducer t/Int t/Int))
  (is-tc-err (map #(inc (t/ann-form % t/Bool))) (t/Transducer t/Int t/Int))
  (is-tc-err (map #(inc %)) (t/Transducer t/Bool t/Int))
  (is-tc-err (map #(inc %)) (t/Transducer t/Int t/Bool))
  (is-tc-err (map (t/fn [% :- t/Int] %)) (t/Transducer t/Int t/Bool))
  (is-tc-err (map #(t/ann-form % t/Nothing)) (t/Transducer t/Int t/Bool))
  (is-tc-e (let [res (map #(do %))]
             (t/ann-form res (t/Transducer t/Nothing t/Any))))
  (is-tc-e (let [res (map (fn [% :- t/Any] %))]
             (t/ann-form res (t/Transducer t/Nothing t/Any))))
  (is-tc-e (let [res (map (fn [% :- t/Any] %))]
             (t/ann-form res (t/Transducer t/Any t/Any))))
  (is-tc-e (let [res (map #(do %))]
             (t/ann-form res (t/Transducer t/Any t/Any))))
  (is-tc-err-messages
    (= {:ex [[(str "Type mismatch:\n\n"
                   "Expected: \t(t/Transducer t/Any t/Nothing)\n\n"
                   "Actual: \t(t/Transducer t/Nothing t/Nothing)")
              {:type-error :clojure.core.typed.errors/type-error, :form 'res}]]}
       (let [res (map #(do %))]
         (t/ann-form res (t/Transducer t/Any t/Nothing)))))
  (is-tc-e (map #(do %)) (t/Transducer t/Int t/Int))
  (is-tc-e (let [map (t/ann-form map (t/All [c a b :..] [[a :-> c] :-> (t/Transducer a c)]))
                 res (map #(do %))]
             (t/ann-form res (t/Transducer t/Int t/Int))))
  (is-tc-e (let [res (map #(do %))]
             (t/ann-form res (t/Transducer t/Int t/Int))))
  (is-tc-err (let [res (map #(do %))]
               (t/ann-form res [t/Any :-> t/Any])))
  (is-tc-e (let [res (map #(do %))]
             (t/ann-form res [t/Nothing :-> t/Any])))
  ;;FIXME better error message, should use Transducer type, not its expansion
  (is-tc-err (let [res (map (fn [% :- t/Int] (do %)))]
               (t/ann-form res [t/Any :-> t/Any])))
  (is-tc-e (let [res (map (fn [% :- t/Int] (do %)))]
             (t/ann-form res [t/Nothing :-> t/Any])))
  (is-tc-e (into [] (map #(do %)) [1]))
  (is-tc-e (into [] (map identity) [1]))
  (is-tc-e (into [] (map identity) [1]) (t/Vec t/Int))
  (is-tc-err (into [] (map identity) [1]) (t/Vec t/Bool))
  (is-tc-e (into [] (map #(t/ann-form % t/Int)) [1]))
  (is-tc-err (into [] (map #(t/ann-form % t/Int)) [true]))
  (is-tc-err (into [] (map #(t/ann-form % t/Bool)) [1]))
  (is-tc-e (into [] (map (fn [% :- (t/Val 1)] %)) [1])
           (t/Vec (t/Val 1)))
  (is-tc-err (into [] (map (fn [% :- (t/Val 1)] %)) [1])
             (t/Vec (t/Val 2)))
  (is-tc-err (into [] (map (fn [% :- (t/Val 1)] %)) [2])
             (t/Vec (t/Val 1)))
  (is-tc-err (into [] (map (fn [% :- (t/Val 1)] %)) [1])
             (t/Vec t/Nothing))
  (is-tc-e (into (t/ann-form [] (t/Vec (t/Val 1)))
                 (map #(do %)) [1]))
  (is-tc-e (into (t/ann-form [] (t/Vec (t/Val 1)))
                 (map identity) [1]))
  (is-tc-e (let [map (t/ann-form map (t/All [c a b :..] [[a :-> c] :-> (t/Transducer a c)]))
                 into (t/ann-form into (t/All [x y :named [a]] [(t/Vec x) (t/Transducer y x) (t/Seqable y) :-> (t/Vec x)]))
                 res (into [1] (map #(do %)) [1])]
             (t/ann-form res (t/Vec (t/Val 1)))
             nil))
  (is-tc-e (let [res (into (t/ann-form [] (t/Vec (t/Val 1)))
                           (map #(do %)) [1])]
             (t/ann-form res (t/Vec (t/Val 1)))
             nil))
  (is-tc-e (let [res (into [] (t/ann-form (map #(do %)) (t/Transducer (t/Val 1) (t/Val 1))) [1])]
             (t/ann-form res (t/Vec (t/Val 1)))
             nil))
  (is-tc-err (let [res (into [] (t/ann-form (map #(do %)) (t/Transducer (t/Val 2) (t/Val 2))) [1])]
               (t/ann-form res (t/Vec (t/Val 1)))
               nil))
  (is-tc-e (into (t/ann-form [] (t/Vec (t/Val 1)))
                 (map #(do %)) [1])
           (t/Vec (t/Val 1)))
  (is-tc-e (into (t/ann-form [] (t/Vec (t/Val 1)))
                 (map #(do %)) []))
  (is-tc-e (into (t/ann-form [] (t/Vec (t/Val 1)))
                 (map #(do %)) [])
           (t/Vec (t/Val 1)))
  (is-tc-err (into (t/ann-form [] (t/Vec (t/Val 2)))
                   (map #(do %)) [1])
             (t/Vec (t/Val 1)))
  (is-tc-err (into (t/ann-form [] (t/Vec (t/Val 2)))
                   (map #(do %)) [2])
             (t/Vec (t/Val 1)))
  (is-tc-e (fn [map :- (t/All [c a b :..] [[t/Any :-> c] :-> [:-> c]])]
             (let [res (t/ann-form (map (fn* [_] true))
                                   [:-> t/Infer])]
               (t/ann-form res [:-> true]))))
  (is-tc-e (fn [map :- (t/All [c a b :..] [[t/Any :-> c] :-> [c :-> c]])]
             (let [res (t/ann-form (map (fn* [_] true))
                                   [true :-> t/Infer])]
               (t/ann-form res [true :-> true]))))
  #_;;TODO perhaps if any wild's exist in return type, we should return a symbolic closure?
  ;; (and remember the return type in the symbolic closure)
  (is-tc-e (fn [map :- (t/All [c a b :..] [[t/Any :-> c] :-> [c :-> c]])]
             (let [res (t/ann-form (map (fn* [_] true))
                                   [t/Infer :-> true])]
               (t/ann-form res [true :-> true]))))
  (is-tc-e (fn [map :- (t/All [c a b :..] [[c :-> c] :-> [c :-> c]])]
             (t/ann-form (map (fn* [x] x))
                         [true :-> true])))
  (is-tc-err (fn [map :- (t/All [c a b :..] [[c :-> c] :-> [c :-> c]])]
               (t/ann-form (map (fn* [x] (t/ann-form x false)))
                           [true :-> true])))
  (is-tc-e (fn [map :- (t/All [c a b :..] [[c :-> c] :-> [c :-> c]])]
             (let [res (t/ann-form (map (fn* [x] x))
                                   [true :-> t/Infer])]
               (t/ann-form res [true :-> true]))))
  (is-tc-e (fn [map :- (t/All [c a b :..] [[t/Any :-> c] :-> [c :-> t/Any]])]
             (t/ann-form (map (fn* [_] true)) [true :-> t/Any])))
  (is-tc-e (fn [map :- (t/All [c a b :..] [[t/Any :-> c] :-> [c :-> t/Any]])]
             (t/ann-form (map (fn* [_] true)) [true :-> t/Any])))
  (is-tc-e (fn [map :- (t/All [c a b :..] [[t/Any :-> c] :-> [c :-> t/Any]])]
             (let [res (t/ann-form (map (fn* [_] true))
                                   [t/Infer :-> t/Any])]
               (t/ann-form res [true :-> t/Any])
               (t/ann-form res [false :-> t/Any])
               (t/ann-form res [t/Any :-> t/Any]))))
  (is-tc-e (fn [map :- (t/All [c] [[t/Any :-> c] :-> [[c :-> t/Any] :-> t/Any]])]
             (let [res (t/ann-form (map (fn* [_] true))
                                   [[t/Infer :-> t/Any] :-> t/Any])]
               (t/ann-form res [[true :-> t/Any] :-> t/Any]))))
  (is-tc-e (fn [map :- (t/All [c] [[:-> c] :-> [[c :-> t/Any] :-> t/Any]])]
             (t/ann-form (map (fn* [] true))
                         [[true :-> t/Any] :-> t/Any])))
  (is-tc-e (fn [map :- (t/All [c a b :..] [[a :-> c] :-> [[c :-> t/Any] :-> [a :-> t/Any]]])]
             (let [res (t/ann-form (map #(do %))
                                   [[t/Infer :-> t/Any] :-> [(t/Val 1) :-> t/Any]])]
               (t/ann-form res [[(t/Val 1) :-> t/Any] :-> [(t/Val 1) :-> t/Any]]))))
  (is-tc-e (let [res (t/ann-form (map #(do %))
                                 (t/Transducer (t/Val 1) t/Infer))]
             (t/ann-form res (t/Transducer (t/Val 1) (t/Val 1)))))
  (is-tc-err (into [] (map #(do %)) [2])
             (t/Vec (t/Val 1)))
  (is-tc-err (into [] (map #(do %)) [1])
             (t/Vec t/Nothing))
  (is-tc-err (fn [into :- (t/All [x y :named [a]] [(t/Vec x) (t/Transducer y x) (t/Seqable y) :-> (t/Vec x)])
                  map :- (t/All [c a b :..] [[a :-> c] :-> (t/Transducer a c)])]
               (let [res (into [] (map #(do %)) [2])]
                 (t/ann-form res (t/Vec (t/Val 1))))))
  (is-tc-err (let [res (into [] (map #(do %)) [2])]
               (t/ann-form res (t/Vec t/Nothing))))
  (is-tc-err (into (t/ann-form [] (t/Vec t/Nothing))
                   (t/ann-form (map #(do %)) (t/Transducer (t/Val 2) (t/Val 2)))
                   (t/ann-form [2] (t/Vec (t/Val 2))))
             (t/Vec (t/Val 1)))
  (is-tc-err (into (t/ann-form [] (t/Vec (t/Val 1)))
                   (t/ann-form (map #(do %)) (t/Transducer (t/Val 2) (t/Val 2)))
                   (t/ann-form [2] (t/Vec (t/Val 2))))
             (t/Vec (t/Val 1)))
  (is-tc-err (fn [x :- (t/Vec (t/Val 1))
                  xf :- (t/Transducer (t/Val 2) (t/Val 2))
                  y :- (t/Vec (t/Val 2))]
               :- (t/Vec (t/Val 1))
               (into x xf y)))
  (is-tc-e (fn [x :- (t/Vec (t/Val 1))
                xf :- (t/Transducer (t/Val 2) (t/Val 1))
                y :- (t/Vec (t/Val 2))]
             :- (t/Vec (t/Val 1))
             (into x xf y)))
  (is-tc-e (do (t/ann pour (t/All [x y] [(t/Vec x) [y :-> x] (t/Seqable y) :-> (t/Vec x)]))
               (def pour #(into %1 (map %2) %3))
               (pour [] #(do %) [1])))
  (is-tc-e (do (t/ann pour (t/All [x y] [(t/Vec x) [y :-> x] (t/Seqable y) :-> (t/Vec x)]))
               (def pour #(into %1 (map %2) %3))
               (let [res (pour [] #(do %) [1])]
                 (t/ann-form res (t/Vec (t/Val 1)))
                 nil)))
  (is-tc-e (do (t/ann pour (t/All [x y] [(t/Vec x) [y :-> x] (t/Seqable y) :-> (t/Vec x)]))
               (def pour #(into %1 (map %2) %3))
               (pour [] #(do %) [1]))
           (t/Vec (t/Val 1)))
  (is-tc-err (do (t/ann pour (t/All [x y] [(t/Vec x) [y :-> x] (t/Seqable y) :-> (t/Vec x)]))
                 (def pour #(into %1 (map %2) %3))
                 (pour [] #(do %) [1]))
             (t/Vec (t/Val 2)))
  (is-tc-e (into [] (map #(do %)) [1])
           (t/Vec (t/Val 1)))
  (is-tc-e (let [map (t/ann-form map (t/All [c a b :..] [[a :-> c] :-> (t/Transducer a c)]))
                 into (t/ann-form into (t/All [x y :named [a]] [(t/Vec x) (t/Transducer y x) (t/Seqable y) :-> (t/Vec x)]))]
             (into [] (map #(do %)) [1]))
           (t/Vec (t/Val 1)))
  (is-tc-e (do (t/ann map* (t/All [c a b :..] [[a :-> c] :-> [a :-> c]]))
               (def map* #(do %))
               (t/ann pour (t/All [x y] [(t/Vec x) [y :-> x] (t/Seqable y) :-> (t/Vec x)]))
               (def pour #(into %1 (map %2) %3))
               (pour [] (map* #(do %)) [1]))
           (t/Vec (t/Val 1)))
  (is-tc-e (into [] (map #(do %)) [1])
           (t/Vec t/Any))
  (is-tc-e (let [res (into [] (map (fn [% :- (t/Val 1)] %)) [1])]
             (t/ann-form res (t/Vec (t/Val 1)))
             nil))
  (is-tc-e (let [into (t/ann-form into (t/All [x y :named [a]] [(t/Vec x) (t/Transducer y x) (t/Seqable y) :-> (t/Vec x)]))
                 xf (t/ann-form (map (fn [% :- (t/Val 1)] %)) (t/Transducer (t/Val 1) (t/Val 1)))
                 res (into [] xf [1])]
             (t/ann-form res (t/Vec (t/Val 1)))
             nil))
  (is-tc-err (let [f (t/ann-form #(do %) [(t/Val 1) :-> (t/Val 1)])]
               (clojure.core.typed/print-env "f should not be SymbolicClosure!")
               (t/ann-form f [(t/Val 2) :-> (t/Val 2)])
               nil))
  (is-tc-e (let [f #(do %)]
             (t/ann-form f [(t/Val 1) :-> (t/Val 1)])
             (t/ann-form f [(t/Val 2) :-> (t/Val 2)])
             nil))
  (is-tc-err (let [f #(do %)]
               (t/ann-form f [(t/Val 1) :-> (t/Val 2)])
               (t/ann-form f [(t/Val 2) :-> (t/Val 2)])
               nil))
  (is-tc-e (let [xf (map #(do %))]
             (t/ann-form xf (t/Transducer (t/Val 1) (t/Val 1)))
             (t/ann-form xf (t/Transducer (t/Val 2) (t/Val 2)))
             nil))
  (is-tc-err (let [xf (t/ann-form (map #(do %)) (t/Transducer (t/Val 1) (t/Val 1)))]
               (clojure.core.typed/print-env "xf should not be SymbolicClosure!")
               (t/ann-form xf (t/Transducer (t/Val 2) (t/Val 2)))
               nil))
  (is-tc-e (let [into (t/ann-form into (t/All [x y :named [a]] [(t/Vec x) (t/Transducer y x) (t/Seqable y) :-> (t/Vec x)]))
                 xf (t/ann-form (map #(do %)) (t/Transducer (t/Val 1) (t/Val 1)))
                 _ (t/ann-form xf (t/Transducer (t/Val 1) (t/Val 1)))
                 res (into [] xf [1])]
             (t/ann-form res (t/Vec (t/Val 1)))
             nil))
  (is-tc-e (let [into (t/ann-form into (t/All [x y :named [a]] [(t/Vec x) (t/Transducer y x) (t/Seqable y) :-> (t/Vec x)]))
                 xf (t/ann-form (map #(do %)) (t/Transducer (t/Val 1) (t/Val 1)))
                 res (into [] xf [1])]
             (t/ann-form res (t/Vec (t/Val 1)))
             nil))
  (binding [clojure.core.typed.util-vars/*verbose-types* true]
    (is-tc-e (let [into (t/ann-form into (t/All [x y :named [a]] [(t/Vec x) (t/Transducer y x) (t/Seqable y) :-> (t/Vec x)]))
                   res (into [] (map #(do %)) [1])]
               (clojure.core.typed/print-env "foo")
               (t/ann-form res (t/Vec (t/Val 1)))
               nil)))
  )
halgari/naiad
(ns naiad.core-test
  (:require [clojure.test :refer :all]
            [clojure.core.async :as async]
            [naiad :as df :refer [flow-result]]))

(deftest transducer-fusing
  (testing "multiple simple transducers become one"
    (let [make-graph (fn []
                       (->> [-1 1 2 3 -33]
                         (df/filter pos?)
                         (df/filter even?)
                         (df/filter integer?)
                         (df/filter number?)))]
      (is (= (flow-result
               (make-graph))
            [2]))
aliostad/deep-learning-lang-detection
(ns futura.stream-tests
  (:require [clojure.core.async :refer [put! take! chan <! >! <!! close!] :as async]
            [clojure.test :refer :all]
            [clojure.java.io :as io]
            [clojure.pprint :refer [pprint]]
            [manifold.stream :as ms]
            [futura.stream :as stream]
            [futura.promise :as p])
  (:import org.reactivestreams.Publisher
           org.reactivestreams.Subscriber
           org.reactivestreams.Subscription))

(deftest publisher-composition
  (testing "Using simple map transducer."
    (let [p (->> (stream/publisher [1 2 3 4 5 6])
                 (stream/transform (map inc)))]
      (is (= [2 3 4 5 6 7] (into [] p)))))

  (testing "Using take + map transducer"
    (let [p (->> (stream/publisher [1 2 3 4])
                 (stream/transform (take 2))
                 (stream/transform (map inc)))]
      (is (= [2 3] (into [] p)))))

  (testing "Using take + map + partition-all transducer"
    (let [p (->> (stream/publisher [1 2 3 4 5 6])
                 (stream/transform (take 5))
                 (stream/transform (map inc))
                 (stream/transform (partition-all 2)))]
    (is (= [[2 3] [4 5] [6]] (into [] p)))))
)