Hello,<br><br>CL-Store can handle storing normal circular lists, but it can't store correctly the circularity on lists like this particular list:<br><br><span style="font-family: courier new,monospace;">'(0 . #1=(1 2 3 . #1#))</span><br>
<br>The problem is that the circularity is inside the list. Not that I am actually using this kind of list, I just ran into this bug for curiosity.<br><br><span style="font-family: courier new,monospace;">cl-user> (setf *print-circle* t)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">t</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">cl-user> (cl-store:store '(0 . #1=(1 2 3 . #1#)) "test")</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">(0 . #1=(1 2 3 . #1#))</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">cl-user> (cl-store:restore "test")</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">#1=(0 1 2 . #1#)</span><br><br>The problem is that safe-length returns 3 as the length for the given list. A possible solution is to make safe-length test if the circularity found references the list itself. If it does, than return the value it already returned. If not, it returns (values 1 (cdr list)). This makes cl-store to store only a single cons and repeat the same process to the cdr of the list. This simple change should make cl-store backward compatible and will fix this issue, although it is not optimal to, for instance, this list:<br>
<br><font face="courier new,monospace">'(0 1 [...] </font>1000000 . #1=(1000001 . #1#))<br><br>It would take something in the order of factorial(10^6) ~ 10^12 steps to execute this.<br><br>I attached a patch which implements this idea, plus a regression test for this case. Initially I wrote the test binding a list to <span style="font-family: courier new,monospace;">'(0 . #1=(1 2 3 . #1#))</span>, but in case of failure it would hang, it printed the form as if *print-circle* = nil even if *print-circle*=t.<br>
<br>The regression test fails for the current version (I tested it) but passes successfully when the patch is applied.<br><br>Actually, there is still a bug in this sense, <br><br>Gustavo.<br>