<div dir="ltr">Hi everyone,<div><br></div><div>I&#39;m currently writing a Scheme interpreter in Swift. My original plan was to use Swift&#39;s memory management to handle objects in Scheme. Unfortunately, Scheme&#39;s data structures are inherently cyclic and I&#39;m struggling to find a good approach to manage memory via ARC.</div><div><br></div><div>An example that highlights the problem are arrays that contain elements that refer to the array itself. In Scheme, such arrays can be easily created like this:</div><div><br></div><div><font face="monospace, monospace">  (define vec (vector 1 2 3))</font></div><div><font face="monospace, monospace">  (vector-set! vec 1 vec)</font></div><div><br></div><div>Vector <font face="monospace, monospace">vec</font> now refers to itself via index 1.</div><div><br></div><div>For representing a Scheme array, my interpreter simply uses an object that wraps a Swift array. The array elements point at Scheme objects. So, they could point at the array itself. Since I don&#39;t want to loose objects that are linked off the array only, I need to use strong references in the array. Obviously, this creates a serious memory leak. Here&#39;s some code illustrating the design and the construction of <font face="monospace, monospace">vec</font>:</div><div><br></div><div><div><font face="monospace, monospace">  enum SchemeValue {</font></div><div><font face="monospace, monospace">    case Nil</font></div><div><font face="monospace, monospace">    case Num(Int)</font></div><div><font face="monospace, monospace">    indirect case Cons(SchemeValue, SchemeValue)</font></div><div><font face="monospace, monospace">    case Vector(WrappedArray&lt;SchemeValue&gt;)</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  class WrappedArray&lt;T&gt; {</font></div><div><font face="monospace, monospace">    var array: [T]</font></div><div><font face="monospace, monospace">    init(_ elem: T...) {</font></div><div><font face="monospace, monospace">      self.array = elem</font></div><div><font face="monospace, monospace">    }</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  let wa = WrappedArray&lt;SchemeValue&gt;(.Num(1), .Num(2), .Num(3))</font></div><div><font face="monospace, monospace">  let vec = SchemeValue.Vector(wa)</font></div><div><font face="monospace, monospace">  wa.array[1] = vec</font></div></div><div><br></div><div>I haven&#39;t found a good way to address the issue. What I would ideally need is manual access to retain/release functions. I would also be willing to write my own memory manager for such objects, but also this seems to be impossible in Swift. As a workaround, I currently built a mark/sweep garbage collector for all Scheme objects I allocate (by keeping them all in a weak object pool — also hand-written because it doesn&#39;t exist in Swift). But I consider this application-specific garbage collector that runs on top of ARC a huge heck.</div><div><br></div><div>So, my question is: What are Swift programmers supposed to do if they are dealing with inherently cyclic data structures that cannot be broken up via weak references? It almost seems like there&#39;s some memory management functionality missing in Swift that makes this possible.</div><div><br></div><div>== Matthias</div><div><br></div></div>