Getting Seqable from java collections

28 views
Skip to first unread message

Mark Feeney

unread,
Jul 12, 2015, 11:30:19 PM7/12/15
to clojure-c...@googlegroups.com
Hi all.

Should `(map identity (java.util.HashMap.)` type check?

----------
user=> (do (require '[clojure.core.typed :as t]) (t/cf (map identity (java.util.HashMap.))))
Type Error (/tmp/form-init3280987779190725166.clj:1:49) Polymorphic function map could not be applied to arguments:
Polymorphic Variables:
        c
        a
        b

Domains:
        [a b ... b -> c] (t/NonEmptySeqable a) (t/NonEmptySeqable b) ... b
        [a b ... b -> c] (t/U (Seqable a) nil) (t/U (Seqable b) nil) ... b

Arguments:
        (t/All [x] [x -> x :filters {:then (! (t/U nil false) 0), :else (is (t/U nil false) 0)} :object {:id 0}]) java.util.HashMap

Ranges:
        (t/NonEmptyASeq c)
        (t/ASeq c)

in: (map identity (new java.util.HashMap))




ExceptionInfo Type Checker: Found 1 error  clojure.core/ex-info (core.clj:4403)
----------

I also tried `(map identity (into {} (java.util.HashMap.))`, but `into` fails in a similar way (wants a Seqable, which java.util.Map isn't).

Thanks!


Mark

Ambrose Bonnaire-Sergeant

unread,
Jul 15, 2015, 2:56:56 AM7/15/15
to core.typed
Does (seq (new java.util.HashMap)) type check?

(map identity c) usually does type check because identity is polymorphic.

Thanks,
Ambrose

Mark Feeney

unread,
Jul 15, 2015, 11:38:47 PM7/15/15
to clojure-c...@googlegroups.com
Hm, no (seq (new java.util.HashMap)) doesn't check (core.typed 3.0.7, nor anything back to 0.2.58).  Also it prints the error twice? -- see below.

The following do work, though:

(seq (new java.util.HashSet)) ;; (t/Option (t/NonEmptyASeq t/Any))
(seq (new java.util.ArrayList)) ;; (t/Option (t/NonEmptyASeq t/Any))

Maybe java.util.Map needs to be considered a t/ASeq? This feels a bit bizarre since it's actually the entrySet that is the seq... Clojure has some special handling for this when you call seq on a j.u.Map though: https://github.com/clojure/clojure/blob/35563c1d64406ce9c57e93a3d1d83cbd0a21bbab/src/jvm/clojure/lang/RT.java#L523-L524

--

(t/cf (seq (new java.util.HashMap)))

Type Error (/tmp/form-init3382888200290709883.clj:5:9) Polymorphic function seq could not be applied to arguments:
Polymorphic Variables:
        x

Domains:
        (clojure.core.typed/Option (Seqable x))

Arguments:
        java.util.HashMap

Ranges:
        (clojure.core.typed/Option (clojure.core.typed/NonEmptyASeq x))


in: (seq (new java.util.HashMap))


Type Error (/tmp/form-init3382888200290709883.clj:5:9) Polymorphic function seq could not be applied to arguments:
Polymorphic Variables:
        x

Domains:
        (clojure.core.typed/Option (Seqable x))

Arguments:
        java.util.HashMap

Ranges:
        (clojure.core.typed/Option (clojure.core.typed/NonEmptyASeq x))


in: (seq (new java.util.HashMap))

Mark Feeney

unread,
Jul 28, 2015, 1:32:33 AM7/28/15
to core.typed, mark....@gmail.com
Any advice/thoughts here?  I've worked around my issue, but remain interested in what a better approach might be. 

Couple ideas:
1) accept and force user to add a call to .entrySet (seems unfortunate)
2) Make j.u.Map appear Seqable (unsure about implications)

Many thanks,
Mark
Reply all
Reply to author
Forward
0 new messages