<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div dir="ltr" class=""><br class=""><div class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><span class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="font-family:Alegreya-Regular;font-size:15px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="">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's some memory management functionality missing in Swift that makes this possible.</div></div></blockquote></div><br class=""></span><div class="">You need to write code that walks through the data structures, recognizes which parts are no longer live, and clears the strong references to them. This is one of the age-old fundamental problems with reference counting — I remember dealing with it in Smalltalk-80, whose GC was based on refcounts.</div><div class=""><br class=""></div><div class="">I think you’re going to have to end up writing a mark/sweep garbage collector for your Scheme interpreter. A basic implementation is really simple.</div></div></blockquote><div class=""><br class=""></div><div class="">That's what I ended up doing. It just feels like a huge hack: it messes up your code and the impact on the performance of the interpreter is serious.</div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class="">Just off the top of my head, I think you’d use only unowned references between your Scheme objects. Then to keep the objects alive, you have a master array/set/whatever that holds strong references to all of them. After doing the recursive marking of all your objects, you traverse the master set and remove all the objects whose mark flags aren’t set.<br class=""></div></div></blockquote><div class=""><br class=""></div><div class="">Yes, that was my first attempt. The problem is that Swift 2 has no good support for weak references beyond weak properties. I'm using arrays throughout my code and those use strong references. Furthermore, my basic data structure is an enum with associated values. I haven't figured out a way to refer to the associated values weakly. This doesn't work:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="color:rgb(39,42,216)" class=""> enum</span> SchemeValue {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <font color="#272ad8" class="">...</font></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color:rgb(39,42,216)" class="">case</span> Vector(<b class="">weak</b> WrappedArray<SchemeValue>)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> }</div></div><div class=""><br class=""></div><div class="">So, what I ended up doing is to implement a mark/sweep garbage collector which is holding only weak references in an object pool. All references in the application are strong. After the mark phase, I then clear objects that are not marked but that are still weakly linked in the object pool. These are the objects that have cyclic dependencies. I just clear them (reset all references) and ARC deallocates them.</div><div class=""><br class=""></div><div class="">This approach has the same implementation problem I describe above when it comes to implement an array of weak references. I use something like this:</div><div class=""><br class=""></div><div class=""><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="color:rgb(39,42,216)" class=""> struct</span> WeakReference<T: AnyObject> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color:rgb(39,42,216)" class="">weak</span> <span style="color:rgb(39,42,216)" class="">var</span> obj: <span style="color:rgb(112,61,170)" class="">T</span>?</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> }</div></div><div class=""><span style="font-family:Menlo;font-size:11px;color:rgb(39,42,216)" class=""> class</span><span style="font-family:Menlo;font-size:11px" class=""> ObjectPool<T: AnyObject> {</span><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color:rgb(39,42,216)" class="">var</span> references: [<span style="color:rgb(79,129,135)" class="">WeakReference</span><<span style="color:rgb(112,61,170)" class="">T</span>>]</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""> ...</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><br class=""></div></div><div class="">It does have the benefit that this ugly workaround via struct <font face="monospace, monospace" class="">WeakReference<T></font> is only needed in the <font face="monospace, monospace" class="">ObjectPool<T></font> implementation and isn't spread throughout the whole codebase.</div><div class=""><br class=""></div><div class="">Nevertheless, this collaborative garbage collection scheme where the mark/sweep collector handles cycles and ARC handles the rest doesn't feel like a good solution. It's, at best, a workaround that is impossible to optimize. This is why I was wondering if there's anything else I could do...</div><div class=""><br class=""></div><div class="">== Matthias</div><div class=""><br class=""></div></div></div></div></div>
</body></html>