Strange protocol behaviour

14 views
Skip to first unread message

Steve Purcell

unread,
May 20, 2010, 8:43:04 AM5/20/10
to clo...@googlegroups.com
I'm loving protocols, but I keep having to restart my JVM to avoid a puzzling issue when changing protocol definitions.

Here's the simplest way to reproduce the problem:

Start with file protoproblem/proto.clj:

(ns protoproblem.proto)

(defprotocol Steps
(one [x])
(two [x]))

and file protoproblem/impl.clj:

(ns protoproblem.impl
(:require [protoproblem.proto :as proto]))

(deftype ArraySteps [a]
proto/Steps
(one [x] (first a))
(two [x] (second a)))

In the repl, everything works as expected:

user> (load "protoproblem/proto")
nil
user> (load "protoproblem/impl")
nil
user> (protoproblem.proto/one (protoproblem.impl.ArraySteps. [1 2]))
1

Now, we redefine the protocol by commenting out the 'one' method def in proto.clj, and then reloading it:

user=> (load "protoproblem/proto")
nil
user=> (protoproblem.proto/one (protoproblem.impl.ArraySteps. [1 2]))
java.lang.NullPointerException (NO_SOURCE_FILE:9)
user=> (load "protoproblem/impl")
java.lang.IllegalArgumentException: Can't define method not in interfaces: one (impl.clj:5)

That's pretty much as expected. But what if we try to get back to how things were, by reversing the changes in proto.clj, and reloading? This is where the problems arise:

user=> (load "protoproblem/proto")
nil
user=> (load "protoproblem/impl")
nil
user=> (protoproblem.proto/one (protoproblem.impl.ArraySteps. [1 2]))
java.lang.IllegalArgumentException: No implementation of method: :one of protocol: #'protoproblem.proto/Steps found for class: protoproblem.impl.ArraySteps (NO_SOURCE_FILE:0)

Ouch!

At this point, I have to restart my JVM to proceed, which is making incremental development of protocols-based code unusually tedious.

I initially encountered the behaviour using "C-c C-k" under slime/swank-clojure, but the above transcript is from a plain command-line repl, using a Clojure 1.2 snapshot from today. (The same thing happened with a snapshot from 2 weeks ago.)

Is this a classloader issue, or something else? Any help greatly appreciated.

-Steve

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Steve Purcell

unread,
May 20, 2010, 1:19:30 PM5/20/10
to clo...@googlegroups.com
Before anyone spends time investigating, this has been accepted as an issue:

https://www.assembla.com/spaces/clojure/support/tickets/353

My workaround for now is to use reify in place of deftype.

-Steve
Reply all
Reply to author
Forward
0 new messages