Search code examples
lispcommon-lisp

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

  • 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)