Odd name-sensitive behaviour

37 views
Skip to first unread message

Chris Spencer

unread,
Mar 20, 2013, 6:07:01 AM3/20/13
to clojure-c...@googlegroups.com
Was just trying out some basic protocol/datatype types and found an odd case where the naming of the protocol changes whether an exception is thrown or not.

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

(t/ann-protocol AddProtoc
  adder [AddProtoc Number -> AddProtoc])

(t/defprotocol> AddProtoc
  (adder [this amount]))

(t/ann-datatype Accumulator [t :- Number])

(deftype Accumulator [t]
  AddProtoc
  (adder [_ i] (Accumulator. (+ t i))))

(t/ann t [Number -> Accumulator])
(defn t [i] (Accumulator. i))

(t/ann t2 [Number -> AddProtoc])
(defn t2 [i] (Accumulator. i))

(t/check-ns)

"Checking line:" 4
"Checking line:" 7
"Checking line:" 10
"Checking line:" 12
"Checking line:" 16
"Checking line:" 17
"Checking line:" 19
"Checking line:" 20
IllegalArgumentException Multiple methods in multimethod 'subtype*' match dispatch value: [clojure.core.typed.Protocol clojure.core.typed.Protocol :clojure.core.typed/clojure] -> [clojure.core.typed.Protocol :clojure.core.typed/Type :clojure.core.typed/clojure] and [clojure.core.typed.Protocol clojure.core.typed.Protocol :clojure.core.typed/default], and neither is preferred  clojure.lang.MultiFn.findAndCacheBestMethod (MultiFn.java:136)

Doesn't occur if name of protocol changed to AddProto. The same exception is thrown when named AddProto but with an incompatible type given for the adder in the protocol (such as [AddProto Number -> Number]). Both are thrown on line 20 (the checking of t2)

This is with clojure 1.4 on windows.

Chris Spencer

unread,
Mar 20, 2013, 6:15:06 AM3/20/13
to clojure-c...@googlegroups.com
Of course, I realise the actual issue just after posting: can't just reload the namespace in repl. So that's a bit more understandable.

However, setting the protocol definition to:

(t/ann-protocol AddProtoc
  adder [AddProtoc Number -> Number])

With the above code now checks fine, even though adder returns an Accumulator in its definition.

Ambrose Bonnaire-Sergeant

unread,
Mar 20, 2013, 10:56:13 AM3/20/13
to core.typed
(Accidentally didn't to send this to the list)

On Wed, Mar 20, 2013 at 9:00 PM, Chris Spencer <chris.ag...@gmail.com> wrote:
Seems the return type isn't being checked properly in some circumstances. If I set the type of adder to something like [AddProtocol Number -> String] then:

(adder [this i]
  (let [ret (Accumulator. (+ total i))]
    ret))

Properly complains, whereas:

(adder [this i]
  (Accumulator. (+ total i)))

does not.

Thanks, that really helps narrow the problem. I've created an issue: http://dev.clojure.org/jira/browse/CTYP-21
 

The naming issues seem to be an artefact of reloading a type checked namespace in the repl after changing the name of a type or protocol, with is easy to live with. (renaming protocols/types in reloaded namespaces always tends to bad behaviour anyway).

The way it currently works is meant to help with REPL driven development. Just re-evaluating an ann-protocol should update its type. The unsurprisingly comes with all the pitfalls of (a persistent) REPL.


Thanks for your work on this by the way, impressive work!

Cheers!
Ambrose

Ambrose Bonnaire-Sergeant

unread,
Mar 20, 2013, 10:20:30 PM3/20/13
to core.typed, Chris Spencer

Ambrose Bonnaire-Sergeant

unread,
Mar 21, 2013, 12:47:33 AM3/21/13
to core.typed, Chris Spencer
Doh, I probably can't reproduce because I just fixed it yesterday :)


I've resolved the issue on Jira.

Thanks,
Ambrose
Reply all
Reply to author
Forward
0 new messages