Clojure

cannot close over mutable fields (in deftype)

Details

  • Type: Defect Defect
  • Status: Open Open
  • Priority: Major Major
  • Resolution: Unresolved
  • Affects Version/s: None
  • Fix Version/s: Backlog
  • Component/s: None
  • Labels:
  • Approval:
    Vetted

Description

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)

Activity

Hide
Assembla Importer added a comment -
Show
Assembla Importer added a comment - Converted from http://www.assembla.com/spaces/clojure/tickets/274
Hide
Assembla Importer added a comment -

donmullen said: Updated each run to [_] for new syntax.

Now gives exception listed.

Show
Assembla Importer added a comment - donmullen said: Updated each run to [_] for new syntax. Now gives exception listed.
Hide
Assembla Importer added a comment -

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

Show
Assembla Importer added a comment - 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
Hide
Nicola Mometto added a comment - - edited

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)

Show
Nicola Mometto added a comment - - edited 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)
Hide
Nicola Mometto added a comment -

Related tickets: CLJ-1075 CLJ-1023

Show
Nicola Mometto added a comment - Related tickets: CLJ-1075 CLJ-1023

People

  • Assignee:
    Unassigned
    Reporter:
    Anonymous
Vote (2)
Watch (4)

Dates

  • Created:
    Updated: