[Openmcl-devel] Strange LISP Clozure problems

Robert Goldman rpgoldman at sift.info
Fri Oct 1 09:47:07 PDT 2010

On 10/1/10 Oct 1 -11:27 AM, Lonnie Cumberland wrote:
> Hello Robert,
> Thanks for the response and suggestion.
> Actually, it not a database as the list grows both in number if
> entries as well as the size of each of the two sub-list. It's more of
> a collections of changing number theory patterns problem more so than
> a database.

Well, having more entries isn't a problem if your list is represented as
an array.  See VECTOR-PUSH-EXTEND to do that.

It would help if you were to explain how this data structure is to be
accessed.  Is the first element a key?  what are the two "sub-lists"?

I'm assuming you have something like this

(defstruct my-record
  (index 0 :type fixnum)
  (sublist1 nil :type list)
  (sublist2 nil :type list)
  (some-other-thing 0 :type fixnum))

I don't see any reason why you couldn't keep them in an array instead of
a list, and if you can, you should, since you get constant-time access
if the index is really an index, and you can destructively modify them

(setf (my-record-sublist1 (aref pattern-vector n)) <some-damn-thing>)

Also, you can iterate over the array easily (see discussion of
fill-pointers); just as easily as with a list, and more efficiently,
since you need only do pointer arithmetic and not pointer-chasing.

if you want more successful help, it would be a good idea to tell us
what these records are and, in particular, what the sublists are and
what the first and fourth fields are.  Without knowing how they are to
be used, it's almost impossible to give useful suggestions about data
structures except to suggest that as a novice you be VERY VERY cautious
(i.e., don't do this) about destructively modifying lists.


> I actually have a dynamic lattice in which. The total number of
> patterns is initialized to 10,000 and then after the first iteration a
> great many of them have been deleted from another function that I
> have. From that point and based upon the information in the
> "sub-lists" (ie.. the 2 lists within each pattern entry) more patterns
> are added back up to the approximate 10,000 value.
> The process is then repeated on the next iteration such that
> "patterns" that do not meet some criteria are deleted, the sub-lists
> of each pattern are updated (appended), and then more patterns are
> added.
> The process continues until a stopping point and then the final
> "surviving" patterns are evaluated for a solution. This process works
> easily on a spreadsheet provided that the tests are small, so now it
> is time to code it up into a full implementation.
> Cheers,
> Lonnie
> On Fri, Oct 1, 2010 at 12:12 PM, Robert Goldman <rpgoldman at sift.info> wrote:
>> On 10/1/10 Oct 1 -11:00 AM, Lonnie Cumberland wrote:
>>> Thanks everyone. You have given me some really useful information
>>> which should help me to re-organize a bit in my project.
>>> It still seems strange since it looks like I will have to use
>>> "copy-tree" to manage the lists, and will have to find a clean
>>> solution for my problem.
>>> I was using a single list approach as I described in the original
>>> post, but am not sure how to cleanly implement that given that, if I
>>> understand correctly that "replace-if and replace-if-not and rplacd
>>> and others" include this same type of shared data approach.
>>> I just wanted to have a simple list of the format ((1 (1 2 ....) (2 3
>>> ...) 2) ......) and cleanly grow "append" elements to each of the
>>> internal lists as my code iterates.
>>> Lisp is a great language, but I can see that I have a lot to learn still.
>> Just a suggestion --- why do you think a list is a good data structure
>> for this db, anyway?  If the lists are always the same length, why not
>> use a (fixed-length) array, which is more amenable to
>> in-place/destructive modification?  And, for that matter, if the first
>> element is the key (as it seems to be), then you could get constant time
>> access with aref instead of linear time access with nth or find....
>> Cheers,
>> r
>>> Thanks again for all of the help,
>>> Lonnie
>>> On Fri, Oct 1, 2010 at 11:49 AM, Jon S. Anthony <j-anthony at comcast.net> wrote:
>>>> Hi,
>>>> I would also suggest looking at copy-tree.  However, I would suggest
>>>> even more strongly to reflect on why the general case of "make copy" is
>>>> as vague and difficult as the general case of "is equal" and would refer
>>>> you to:
>>>> http://www.nhplace.com/kent/PS/EQUAL.html
>>>> for some great elucidation.
>>>> /Jon
>>>> On Fri, 2010-10-01 at 09:57 -0400, Lonnie Cumberland wrote:
>>>>> Greetings All,
>>>>> I am working on some code in lisp and basically have 2 lists now after
>>>>> originally trying with just one where I had the same problem. (I also
>>>>> had a plist version but still get the same problem.)
>>>>> I make a list for a format of
>>>>> ((1  nil nil 1)
>>>>> .
>>>>> .
>>>>> .
>>>>> (n nil nil 1))
>>>>> call it *db*. I then add some values such that the first "nil" is made
>>>>> into a list. [ie.. (1 (2) nil 1) ] and then do this for the whole list
>>>>> in *db* with the function below.
>>>>> (defun add-mod-pres (b)
>>>>>       (mapcar
>>>>>          #'(lambda (row) (setf  (second row) (nconc (second row) (list
>>>>> (mod (first row) b))))) *db*)
>>>>> )
>>>>> The problem comes when I try to make a copy of the *db* and then
>>>>> change some value in the "copied" db.
>>>>> (setf tempdb (copy-list (remove-if-not #'(lambda (row) (equal (first
>>>>> (last row)) (list j))) *db*)))
>>>>> The result I am getting is that things as also being changed in the
>>>>> original *db* as well and it look as though there is something going
>>>>> on with LISP using pointers instead of actually making a copy.
>>>>> The basic code problem is to have my list like:
>>>>> ((1  nil nil 1)
>>>>> .
>>>>> .
>>>>> .
>>>>> (n nil nil 1))
>>>>> and while iterating over some other lists that I have, I grow each
>>>>> list like the below example of a single sublist within *db*:
>>>>> Iteration 1
>>>>> (1 (2) (1) 1)
>>>>> Iteration 2
>>>>> (1 (2 1) (1 5) 1)
>>>>> .
>>>>> .
>>>>> Iteration 10
>>>>> (1 (2 1 3 4 5 4 3 2 1 0) (1 5 3 2 4 5 4 4 5 3) 1)
>>>>> etc....
>>>>> What I am currently getting is that when I modify the (1 5 .... ) list
>>>>> then it also seems to modify the (2 1 .....) list in the *db* and this
>>>>> also happens if I modify the (1 5 ....) list in the tempdb which also
>>>>> modifies the *db* list.
>>>>> There seems to be some shared memory in the lists going on and I don't
>>>>> know how to stop it.
>>>>> Could the "lambda" or "mapcar" functions be the problem?
>>>>> Kind Regards and have a great day,
>>>>> Lonnie T. Cumberland
>>>>> "BTE, bringing people together today to meet the world's energy needs
>>>>> of tomorrow......"
>>>>> The information contained in this transmission is intended only for
>>>>> the person or entity to which it is addressed and may contain
>>>>> confidential and/or privileged material. If you are not the intended
>>>>> recipient of this information, do not review, retransmit, disclose,
>>>>> disseminate, use, or take any action in reliance upon, this
>>>>> information. If you received this transmission in error, please
>>>>> contact the sender and destroy all printed copies and delete the
>>>>> material from all computers.
>>>>> _______________________________________________
>>>>> Openmcl-devel mailing list
>>>>> Openmcl-devel at clozure.com
>>>>> http://clozure.com/mailman/listinfo/openmcl-devel
>>> _______________________________________________
>>> Openmcl-devel mailing list
>>> Openmcl-devel at clozure.com
>>> http://clozure.com/mailman/listinfo/openmcl-devel
>> _______________________________________________
>> Openmcl-devel mailing list
>> Openmcl-devel at clozure.com
>> http://clozure.com/mailman/listinfo/openmcl-devel

More information about the Openmcl-devel mailing list