'How to make a new list with 2 positions of a list changed?

I am a complete newbie in LISP (Common lisp to be exact) and I need to make a function where i can pass the list and 2 arguments, pos1 pos2, that are the elements position in a list, the function should then return a new list with those elements in swapped positions.

Example (changepos '(a b c d) 0 3) -> (D B C A)



Solution 1:[1]

You're right- rotatef modifies the given list. But you can use copy-list or copy-tree (for nested lists) inside your function and modify that copy:

(defun changepos (list i j)
  (let ((new-list (copy-tree list)))
    (rotatef (nth i new-list)
             (nth j new-list))
    new-list))

Tests:

> (defparameter *aa* (list 1 2 3 4 5))
*AA*

> (changepos *aa* 1 3)
(1 4 3 2 5)

> *aa*
(1 2 3 4 5)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Martin Půda