0

I try to remove random elements from a list until the list is empty. My environment is Allegro Lisp, free edition.

(setq set1 '(Nr1 Nr2 Nr3))  
(delete (nth (random (length set1)) set1) set1)  

After some repetitions, the output of sequential calls to delete (and the content of set1) start to look like this:

(NR1 NR2 NR3)  
(NR2 NR3)  
(NR1 NR2)  
(NR1)  
NIL

That is, sometimes items are not deleted, sometimes deleted items reappear. If I use remove there is no such problem.

Is this a bug or do I miss something about delete?

tripleee
  • 175,061
  • 34
  • 275
  • 318
slowman01
  • 13
  • 4

2 Answers2

3

delete is allowed to destroy/mutate/reuse parts of the original list to return the result, this has two implications:

  1. You should use (setf set1 (delete ...))
  2. Mutating a quoted list is not a good idea, just use (setf set1 (list 'Nr1 'Nr2 'Nr3)) instead
6502
  • 112,025
  • 15
  • 165
  • 265
  • I understand 1, now, but not 2. In my, obviously wrong, model of the semantics, both expressions would produce the same list set1. If you care to explain, what am i missing? – slowman01 Dec 18 '22 at 15:13
  • @slowman01: `(list 1 2 3)` is an expression than when evaluated will create a new list by consing three cells; `'(1 2 3)` instead returns a list "literal" and what happens mutating its cells is undefined in Common Lisp (in other words if anything happens it's your fault, you're not supposed to do this but the compiler is not required to raise an error if you do). A quoted list is part of the code... you cannot mutate a program once it has been passed to a compiler or it has been evaluated. Calling `remove` on a quoted list is fine because it doesn't touch the input... – 6502 Dec 18 '22 at 16:03
1

When delete is asked to remove the first element of a list, it is allowed to simply return (cdr list), you need to (setf set1 (delete (nth (random (length set1)) set1)))

coredump
  • 37,664
  • 5
  • 43
  • 77
pjstirling
  • 191
  • 4
  • Small typo (setf set1 (delete (nth (random (length set1)) set1) set1)) Thank you, this makes it clear. Coming from non Lisp languages, I didnt realize variable set1 is nothing more than the first element of the list. – slowman01 Dec 17 '22 at 17:37