[CLJ-1023] non-tail-position try block breaks mutable fields in deftype Created: 08/Jul/12 Updated: 27/Jun/13 Resolved: 03/Dec/12
|Affects Version/s:||Release 1.3, Release 1.4|
|Reporter:||Stuart Sierra||Assignee:||Rich Hickey|
The :unsynchronized-mutable fields of a deftype cannot be set! inside a try block that is not in tail position of the method.
See file *demonstration.clj* for an complete code example.
|Comment by Rich Hickey [ 05/Sep/12 7:07 AM ]|
I looked at this. The problem is that non-tail try blocks turn into closures, and thus the field gets propagated as a constant. IOW this can't work:
I'm not going to re-evaluate the try/closure approach right now, so I recommend you make a helper method that just does the assignment and then call that in the bigger context, as a workaround.
|Comment by Timothy Baldridge [ 03/Dec/12 10:55 AM ]|
Closing this as it requires more than a simple bug fix. If you feel that Rich's work-around is unsatisfactory please create a clojure-dev discussion about rewriting try-catch.
|Comment by Nicola Mometto [ 27/Jun/13 5:33 AM ]|
The patch at ticket CLJ-1226 makes it possible to write
(deftype foo [^:unsynchronized-mutable x] MutableX (set-x [this v] (try (set! (.x this) v)) v))
that is probably a better workaround than writing a helper method