Prev: Confirmed: never, Ever, EVER use nreverse unless you (I meanI) damn well know what is going on
Next: COD SOMA NO PRESCRIPTION | BUY CHEAP SOMA C.O.D. | BUY SOMA WITH COD
From: Kaz Kylheku on 7 Dec 2009 18:06 On 2009-12-07, Mirko <mirko.vukovic(a)gmail.com> wrote: > I had no idea nreverse could reach this deep (amounting to shallow > understanding/thinking?). > > This is the code snippet: > > (let ((data (tecplot-data data-pod var :type :boundary :avg avg))) > (coerce (reverse data) 'vector))) If you don't know that tecplot-data returns a newly allocated list, JFY (just for you), then you have no right to use nreverse. Never use NREVERSE unless you know that something /isn't/ going on; namely sharing. > Now (tecplot-data ... ) amounts to > > (aref (data object) 6) I.e. this does not construct anything new, but only retrieves existing data. No brainer: do not use nreverse. > where (data object) returns a vector of 9 lists. > > `data' never existed in the let construct, and the direct reference to > the original list was maintained across two function calls. What do you mean never existed? The variable called data exists; it just does not hold a newly allocated list. A variable in Lisp is not a box which holds a copy of an object that is different from the contents of any other box. So what you are seeing is not an optimization which gets rid of that box and propagates the original object. What never existed in your program when you used NREVERSE was a private copy of the list, not shared with anything else in the program. That's only because the function you called didn't make one, and neither did your code. Lisp variables are, generally, pointers. Only certain values are not pointers, like small integers (fixnums), and perhaps characters. Things which can fit directly inside the machine word that is being used for representing values, so that they don't have to be allocated elsewhere and pointed at. Lisp function calls pass and return by value, but the value being passed is usually a reference to something. Thus (setf a b) often really means ``make A point to whatever B is pointing to'' (if B in fact is pointing, and not one of those special non-pointer values). You will almost never go wrong in your coding if you - /suspect/ that a Lisp value is really a pointer to something, and that sharing is going on that you don't know about; but - do not /assume/ that two objects understood to be equivalent are the same pointer---use the correct equality for the type.
From: Kaz Kylheku on 8 Dec 2009 12:53
On 2009-12-08, Pascal Costanza <pc(a)p-cos.net> wrote: > Björn Lindberg wrote: >> Mirko <mirko.vukovic(a)gmail.com> writes: >> >>> I had no idea nreverse could reach this deep (amounting to shallow >>> understanding/thinking?). >>> >>> This is the code snippet: >>> >>> (let ((data (tecplot-data data-pod var :type :boundary :avg avg))) >>> (coerce (reverse data) 'vector))) >> >> In this particular case, the perhaps obvious solution is to reverse >> (heh) the order of the reversal and the coercion: >> >> (nreverse (coerce data 'vector)) > > Also dangerous, in case data is already a vector (and you don't know > whether it is one or not because you may change the other parts of your > program later). One day, a student came to moon with a brilliant idea. ``If we just add a reference count field to conses, we can make NREVERSE behave like REVERSE when the count is greater than one ... '' To which Moon replied: [ Everyone: insert your best completion of the story here. ] |