Welcome! Please see the About page for a little more info on how this works.

0 votes
in Compiler by
recategorized by

This is a somewhat contrived example but there is a curious behavior that may or may not be a bug.

Suppose you have the following protocol:

(defprotocol P (f [this]))

And concrete type with a mutable parameter and lock:

(deftype T [^:volatile-mutable x lock]
  P
  (f [this]
    (locking lock
       (set! x true)
       (prn ""))))

Compiler has no problem with this. But move the (prn "") statement outside the (locking …) block and you get:

(deftype T [^:volatile-mutable x lock]
  P
  (f [this]
    (locking lock
      (set! x true))
    (prn "")))

Syntax error (IllegalArgumentException) compiling fn* at (REPL:4:5).
Cannot assign to non-mutable: x

David Miller spotted this behavior in the lastest ClojureCLR (see https://clojure.atlassian.net/browse/CLJCLR-122) and is sleuthing it on his end but the fact the same error is raised in JVM Clojure suggests that either there is a bug in Clojure proper, or some highly counterintuitive rule is at work here, the details of which are probably worth understanding. Why the compiler would view x as non-mutable here is not clear.

1 Answer

0 votes
by
...