<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent questions tagged mutability</title>
<link>https://ask.clojure.org/index.php/tag/mutability</link>
<description></description>
<item>
<title>(deftype) blues - private and mutable field access problems</title>
<link>https://ask.clojure.org/index.php/13890/deftype-blues-private-and-mutable-field-access-problems</link>
<description>&lt;p&gt;New to clojure, trying to define an effective class with mutable fields via deftype, definitions below.&lt;/p&gt;
&lt;p&gt;  My program is single threaded, no one else will ever use my code, promised. I know all the advantages of immutability, but this program makes over 500,000,000 updates, so the GC would be the main actor, not my code. I've tried that.&lt;/p&gt;
&lt;p&gt;Two problems I've got at run time.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*1. ; Execution error (IllegalArgumentException) at layout.core.Individual/idivlCopy (core.clj:161).
    ; No matching field found: fitness for class layout.core.Individual
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I understand that the fields of a deftype are not public, but the code of idivlCopy is in the deftype itself. It seems to me, that the runtime knows (.fitness this) but not (.fitness that).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is the rationale of this behaviour and how can I get around it?&lt;/li&gt;
&lt;li&gt;How can I access the private protected fields (of that) from the private (i.e. deftype) code area?!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;`&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*2. ; Execution error (ClassCastException) at layout.core.Individual/idivlSwap (core.clj:173).
           ; class clojure.core.Vec cannot be cast to class clojure.lang.IEditableCollection
           ;    (clojure.core.Vec and clojure.lang.IEditableCollection are in unnamed module of loader 'app')
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;`&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The annotations tell that both fields are volatile-mutable. Why  is this not known at run time for the chromosome vector? Why can't I (assoc! ) my volatile-mutable chromosome vector-of :char    -s?&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;pre&gt;&lt;code&gt;(definterface IIndividual

  (idivlCopy [that])                      ; Copies that Individual to this
  (idivlSwap [^Integer xP, ^Integer xQ])) ; Swaps two genes in the chromosome
  ; and somme more.
)

(deftype Individual                ; An individual has a fitness value and a chromosome
  [^{:volatile-mutable true}  ^Integer fitness,       ; Integer
   ^{:volatile-mutable true}           chromosome]    ; vector-of :char
 
  IIndividual

	:
	.

  (idivlCopy         ; Copies that Individual to this
    [_, that] 
*1  (set! fitness    (.fitness    that))         ; (set! fitness  999) worked!!
    (set! chromosome (.chromosome that))
    nil)

  (idivlSwap         ; Swaps the genes in the chromosome at alleles P and Q
    [this,
     ^Integer iP,                 ; index of allele P
     ^Integer iQ]                 ; index of allele Q
    (let [gP (chromosome iP),     ; gene  at allele P
          gQ (chromosome iQ)]     ; gene  at allele Q
*2    (assoc! chromosome iP gQ)
      (assoc! chromosome iQ gP)
      nil))

    ; and some more
    :
	.
)
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Clojure</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13890/deftype-blues-private-and-mutable-field-access-problems</guid>
<pubDate>Mon, 20 May 2024 18:15:40 +0000</pubDate>
</item>
<item>
<title>volatile-mutable not recognized in some deftype method subforms</title>
<link>https://ask.clojure.org/index.php/12491/volatile-mutable-recognized-some-deftype-method-subforms</link>
<description>&lt;p&gt;This is a somewhat contrived example but there is a curious behavior that may or may not be a bug.&lt;/p&gt;
&lt;p&gt;Suppose you have the following protocol:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defprotocol P (f [this]))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And concrete type with a mutable parameter and lock:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(deftype T [^:volatile-mutable x lock]
  P
  (f [this]
    (locking lock
       (set! x true)
       (prn &quot;&quot;))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Compiler has no problem with this. But move the &lt;code&gt;(prn &quot;&quot;)&lt;/code&gt; statement outside the &lt;code&gt;(locking …)&lt;/code&gt; block and you get:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(deftype T [^:volatile-mutable x lock]
  P
  (f [this]
    (locking lock
      (set! x true))
    (prn &quot;&quot;)))

Syntax error (IllegalArgumentException) compiling fn* at (REPL:4:5).
Cannot assign to non-mutable: x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;David Miller spotted this behavior in the lastest ClojureCLR (see &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.atlassian.net/browse/CLJCLR-122&quot;&gt;https://clojure.atlassian.net/browse/CLJCLR-122&lt;/a&gt;) 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.&lt;/p&gt;
</description>
<category>Compiler</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12491/volatile-mutable-recognized-some-deftype-method-subforms</guid>
<pubDate>Wed, 21 Dec 2022 17:46:19 +0000</pubDate>
</item>
</channel>
</rss>