Permalink
Browse files

Support doseq>. Tweak primitive subtyping>. Hacks for chunked seqs.

  • Loading branch information...
1 parent 8704059 commit 2450898946a53dc5986026e52144cca61d34eb38 @frenchy64 frenchy64 committed Mar 26, 2013
@@ -48,7 +48,7 @@
[debug-string frm]
frm)
-(declare Method->Function unparse-type unparse-filter)
+(declare Method->Type unparse-type unparse-filter)
;(ann method-type [Symbol -> nil])
(defn method-type
@@ -62,7 +62,7 @@
_ (assert (seq ms) (str "Method " mname " not found"))]
(prn "Method name:" mname)
(doseq [m ms]
- (prn (unparse-type (Method->Function m))))))
+ (prn (unparse-type (Method->Type m))))))
;(ann inst-poly [Any Any -> Any])
(defn inst-poly
@@ -96,19 +96,14 @@
(defn loop>-ann [loop-of bnding-types]
loop-of)
-(comment
- (cf
+(defmacro doseq>
+ "Like doseq but requires annotation for each loop variable:
+ [a [1 2]] becomes [[a :- Long] [1 2]]
+
+ eg.
(doseq> [[a :- (U nil AnyInteger)] [1 nil 2 3]
:when a]
- (inc a))
- )
- )
-
-(defmacro doseq>
- "Repeatedly executes body (presumably for side-effects) with
- bindings and filtering as provided by \"for\". Does not retain
- the head of the sequence. Returns nil."
- {:added "1.0"}
+ (inc a))"
[seq-exprs & body]
(@#'clojure.core/assert-args
(vector? seq-exprs) "a vector for its binding"
@@ -156,14 +151,13 @@
[true
`(loop> [[~seq- :- (~'U nil (~'clojure.lang.Seqable ~k-ann))] (seq ~v),
[~chunk- :- (~'U nil (~'clojure.lang.IChunk ~k-ann))] nil
- [~count- :- ~'clojure.core.typed/AnyInteger] 0,
- [~i- :- ~'clojure.core.typed/AnyInteger] 0]
- (print-env "start-loop")
+ [~count- :- ~'(U Integer Long)] 0,
+ [~i- :- ~'(U Integer Long)] 0]
(if (and (< ~i- ~count-)
;; core.typed thinks chunk- could be nil here
~chunk-)
- (let [~'_ (print-env "after if")
- ~k (.nth ~chunk- ~i-)]
+ (let [;~k (.nth ~chunk- ~i-)
+ ~k (nth ~chunk- ~i-)]
~subform-chunk
~@(when needrec [recform-chunk]))
(when-let [~seq- (seq ~seq-)]
@@ -559,8 +559,8 @@
(let [t (make-FnIntersection
(make-Function
- [(Un -nil (RClass-of Seqable [-any]))]
- (parse-type 'AnyInteger)
+ [(Un -nil (RClass-of Seqable [-any]) (RClass-of clojure.lang.Counted))]
+ (parse-type '(U Integer Long))
nil nil
:object (->Path [(->CountPE)] 0)))]
(add-var-type 'clojure.core/count t)
@@ -569,8 +569,8 @@
(non-nil-return java.lang.Object/getClass #{0})
(override-method clojure.lang.RT/nth
(All [x y]
- (Fn [(Seqable x) AnyInteger -> x]
- [(Seqable x) AnyInteger y -> (U x y)])))
+ (Fn [(U (Indexed x) (Seqable x)) AnyInteger -> x]
+ [(U (Indexed x) (Seqable x)) AnyInteger y -> (U x y)])))
(override-method clojure.lang.Indexed/nth
(All [x y]
@@ -601,3 +601,16 @@
[[-> x] -> x]))
(ann clojure.core/ref (All [x] [x -> (clojure.lang.ARef x x)]))
+
+;; START CHUNK HACKS
+;; These are hacks to get around the expansion of doseq>
+;; Basically, inference isn't good enough to narrow a (Seqable x) to
+;; an (IChunk x), because chunked-seq? needs to be (predicate (IChunk Any)).
+(ann clojure.core/chunked-seq? [Any -> Any])
+(ann clojure.core/chunk-first
+ (All [x]
+ [(Seqable x) -> (clojure.lang.IChunk x)]))
+(ann clojure.core/chunk-rest
+ (All [x]
+ [(Seqable x) -> (ISeq x)]))
+;;END CHUNK HACKS
@@ -560,13 +560,21 @@
;[RClass RClass -> Boolean]
(defn coerse-RClass-primitive
[s t]
- (let [spcls (symbol->Class (:the-class s))
- tpcls (symbol->Class (:the-class t))
- scls (or (boxed-primitives spcls)
- spcls)
- tcls (or (boxed-primitives tpcls)
- tpcls)]
- (isa? scls tcls)))
+ (cond
+ ; (U Integer Long) <: int
+ (and
+ (#{(RClass-of Integer) (RClass-of Long)} s)
+ (#{(RClass-of 'int)} t))
+ true
+
+ :else
+ (let [spcls (symbol->Class (:the-class s))
+ tpcls (symbol->Class (:the-class t))
+ scls (or (boxed-primitives spcls)
+ spcls)
+ tcls (or (boxed-primitives tpcls)
+ tpcls)]
+ (isa? scls tcls))))
(defmethod subtype* [RClass RClass ::clojure]
[{polyl? :poly? :as s}
@@ -1223,3 +1223,11 @@
(deftest map-literal-containing-funapp-test
(is (cf {:bar (identity 1)})))
+
+(deftest doseq>-test
+ (is (cf (clojure.core.typed/doseq> [[a :- (U clojure.core.typed/AnyInteger nil)] [1 nil 2 3]
+ :when a]
+ (inc a))))
+ (is (thrown? Exception
+ (cf (clojure.core.typed/doseq> [[a :- (U clojure.core.typed/AnyInteger nil)] [1 nil 2 3]]
+ (inc a))))))

0 comments on commit 2450898

Please sign in to comment.