Share your thoughts in the 2024 State of Clojure Survey!

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

0 votes
in Records and Types by

Simplest case:

`
user=>
(deftype Bench [#^{:unsynchronized-mutable true} val]
Runnable
(run [_]

(fn [] (set! val 5))))

java.lang.IllegalArgumentException: Cannot assign to non-mutable: val (NO_SOURCE_FILE:5)
`

Functions should be able to mutate mutable fields in their surrounding deftype (just like inner classes do in Java).

Filed as bug, because the loop special form expands into a fn form sometimes:

`
user=>
(deftype Bench [#^{:unsynchronized-mutable true} val]
Runnable
(run [_]

(let [x (loop [] (set! val 5))])))

java.lang.IllegalArgumentException: Cannot assign to non-mutable: val (NO_SOURCE_FILE:9)
`

7 Answers

0 votes
by

Comment made by: importer

donmullen said: Updated each run to (link: _) for new syntax.

Now gives exception listed.

0 votes
by

Comment made by: importer

richhickey said: We're not going to allow closing over mutable fields. Instead we'll have to generate something other than fn for loops et al used as expressions. Not going to come before cinc

0 votes
by

Comment made by: importer

Converted from http://www.assembla.com/spaces/clojure/tickets/274

0 votes
by

Comment made by: bronsa

The patch for CLJ-1226 makes this work:

(deftype Bench [#^{:unsynchronized-mutable true} val] Runnable (run [_] (let [x (loop [] (set! (.val _) 5))])))

If there's interest, I could provide a patch that converts closed over mutable field access by generated fns (for loop/try) into field access on closed over "this", i.e. val -> (.val this)

0 votes
by

Comment made by: bronsa

Related tickets: CLJ-1075 CLJ-1023

0 votes
by

Comment made by: bronsa

CLJ-701 could probably make the loop case working

0 votes
by
Reference: https://clojure.atlassian.net/browse/CLJ-274 (reported by alex+import)
...