Odd name-sensitive behaviour

Showing 1-5 of 5 messages
Odd name-sensitive behaviour Chris Spencer 3/20/13 3:07 AM
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]
  (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))


"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.
Re: Odd name-sensitive behaviour Chris Spencer 3/20/13 3:15 AM
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.
Odd name-sensitive behaviour Ambrose Bonnaire-Sergeant 3/20/13 7:56 AM
(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))]

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!


Re: Odd name-sensitive behaviour Ambrose Bonnaire-Sergeant 3/20/13 7:20 PM

Re: Odd name-sensitive behaviour Ambrose Bonnaire-Sergeant 3/20/13 9:47 PM
Doh, I probably can't reproduce because I just fixed it yesterday :)

I've resolved the issue on Jira.