Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project!

## #621 odd error with sort

lisp error
pending-invalid
Sam Steingold
5
2011-12-08
2011-12-05
No

It is about GNU CLISP strange behaviours. The version 2.33/2.48/2.49 were tested. Can anybody explain this oddness?

(defun xsort (l) (sort l #'<)) ;XSORT
(setq l '(3 1 2)) ;(3 1 2)
(xsort l) ;(1 2 3)
l ; surprize! (1 2 3)

The ordinal lisp function XSORT takes its argument by value but the presence of SORT-function in its body converts argument to passed by reference! Are there any reasonable explanation? BTW the POP-function doesn't make surprize:

(defun xpop (l) (pop l)) ;XPOP
(setq l '(3 1 2)) ;(3 1 2)
(xpop l) ;3
l ;(3 2 1)

## Discussion

• Sam Steingold
2011-12-05

• assigned_to: haible --> sds
• status: open --> pending-invalid

• Sam Steingold
2011-12-05

This bug report is now marked as "pending"/"invalid".
This means that we think that the problem you report is not a problem with CLISP.
Unless you - the reporter - act within 2 weeks, the bug will be permanently closed.
Sorry about the inconvenience - we hope your silence means that you agree that this is not a bug in CLISP.

• Sam Steingold
2011-12-05

This is the way lisp works.
sort is a destructive function, it modifies the list structure.
other CL implementations use different modifications, so l might not be the sorted list.
however, both behaviors are standard-compliant.
try this:
(setq m l)
(setq s (xsort l))
(eq m l) ==> t, because xsort cannot modify l
(eq s l) ==> t, because that's how clisp works

pop is a macro, so it modifies the its argument's value.
xpop is a function, so it cannot modify the value of l.

• Thank you. These behaviours of SORT can produce nightmare side effects. The SORT is destructive. This is ok but XSORT is programmed as normal function! IMHO these odd things should be well documented. IMHO this is severe bug without proper documentation.

• status: pending-invalid --> open-invalid

• Sorry but you example is wrong. See
(setq l '(3 1 2))
(setq m l)
(xsort l)
m; this is completely stupid => (1 2 3)
This is obviously a *nightmare* bug. :-(

• Sam Steingold
2011-12-07

• status: open-invalid --> pending-invalid

• Sam Steingold
2011-12-07

the bug is in you not understanding how lisp works.

http://www.lispworks.com/documentation/HyperSpec/Body/f_sort_.htm
sort and stable-sort destructively sort sequences according to the order determined by the predicate function.
The sorting operation can be destructive in all cases. In the case of a vector argument, this is accomplished by permuting the elements in place. In the case of a list, the list is destructively reordered in the same manner as for nreverse.

m is a symbol.
its symbol-value slot contains a cons cell - the first cons cell in the list.
after sorting that cons cell CAR and CDR contain different referents.

if you want xsort to be non-destructive, you have to copy the argument:
(defun xsort (x) (sort (copy-seq l) #'<))

• Thank you very much! You should only give me this link at first. Yes, there is no any bug. Thank you again.

• status: pending-invalid --> open-invalid

• Sam Steingold
2011-12-08

• status: open-invalid --> pending-invalid