When passing a list to a function, you pass that list, not a copy of it. If the function you are calling modify the list, the list is modified for anybody having that list.
(Technically, a list consists of cons pairs, and you pass the topmost cons pair to the function.)
If you write a lisp function, you have to choice to make it destructive or value based. However, if you make it destructive, you must document it very clearly.
In your case, however, you don't have to copy the entire list. Anything after the element you would like to set can refer to the tail of the original list.
EDIT: the following code use cl-subseq
to copy the start of the list. It is destructively joined with the rest of the list using nconc
, this is fine since we're operating on a new list that no one else can have access to. Also, the 0
case has been simplified, all you need to do is to add the new element to the front of the list using cons
.
(defun my-insert-nth (list element n)
(if (<= n 0)
(cons element list)
(nconc (cl-subseq list 0 n)
(cons element (nthcdr n list)))))