A possible bug involving maps & `extend-protocol`

22 views
Skip to first unread message

Josh Tilles

unread,
Jul 29, 2015, 3:21:22 PM7/29/15
to core.typed
I would expect the following code to typecheck, but I'm stumped on some errors. Am I missing something? Or should I create a bug report on JIRA?

Code:
 (ns demo
   (:require [clojure.core.typed :as t]))

(t/defprotocol Connectable
  (add-connection [db, connection :- java.sql.Connection]
    :- (t/HMap :mandatory {:connection java.sql.Connection}
               :optional {:connection-string String
                          :level t/AnyInteger
                          :legacy Boolean}))
  (get-level [db]
    :- t/AnyInteger))

(extend-protocol Connectable
  String
  (add-connection [s connection] {:connection connection :level 0 :connection-string s})
  (get-level [_] 0)

  clojure.lang.Associative
  (add-connection [m connection] (assoc m :connection connection))
  (get-level [m] (or (:level m) 0))

  nil
  (add-connection [_ connection] {:connection connection :level 0 :legacy true})
  (get-level [_] 0))

Output of (t/check-ns 'demo):
Type Error (demo.clj:19:34) Cannot assoc args `[(t/Val :connection) {:then tt, :else ff}] [java.sql.Connection {:then tt, :else ff} {:id connection__#0}]` on (Associative t/Any t/Any)
in: (assoc m :connection connection)


Type Error (demo.clj:20:18) Type mismatch:

Expected: t/AnyInteger

Actual: t/Any
in: or__4238__auto__


ExceptionInfo Type Checker: Found 2 errors  clojure.core/ex-info (core.clj:4593)


Ambrose Bonnaire-Sergeant

unread,
Jul 30, 2015, 7:47:35 AM7/30/15
to core.typed
I would use t/pred to cast the Associative argument to the expected HMap type
before assoc'ing it.

eg. {:pre [((t/pred (HMap ..)) m)]}

There's a possible enhancement where you might be able to specify the static type
you're expecting for a particular extend-type dispatch, but I haven't thought it through.

Thanks,
Ambrose

Josh Tilles

unread,
Jul 30, 2015, 11:47:24 AM7/30/15
to core.typed, abonnair...@gmail.com
Thanks a bunch Ambrose! That did the trick. (Plus, I now know about clojure.core.typed/pred!)

By the way, is it appropriate to be bringing these sorts of questions to the mailing list? Like, should I instead start with IRC or JIRA?

Ambrose Bonnaire-Sergeant

unread,
Jul 30, 2015, 11:51:11 AM7/30/15
to core.typed
This is the preferred place.
Reply all
Reply to author
Forward
0 new messages