I thought function in elisp can't modify its argument, but it is not true when some special primitive functions such as
delete (not including
setq) are called when defining new function in elisp, for example, in following the value of
x gets changed after calling
(foo x), which is not unexpected and undesired to me.
(defun foo (x) (setcdr x nil)) (progn (setq x '(1 2)) (foo x) x) ;; => (1)
I know I can make a copy of
x before using
setcar to avoid the problem, is this the right way?
Besides, It also looks like it is impossible to write a
setcar implementation in elisp function.
It bothered me when I was writing
my-insert-nth, I had to make a copy of argument
list in function body since
list's value should be changed, while I'm not quite sure.
(defun my-insert-nth (list element n) "Insert ELEMENT at Nth of LIST." (if (<= n 0) (nconc (list element) list) (let ((len (length list))) (if (>= n len) (append list (list element)) ;; FIXME: Why need another copy? Does `defun' already do that? (let ((new-list (copy-sequence list))) (setcdr (nthcdr (1- n) new-list) (cons element (nthcdr n new-list))) new-list))))) (let ((l '(a b c))) (list (my-insert-nth l 'beg 0) (my-insert-nth l 'mid 2) (my-insert-nth l 'end 3))) ;; => ((beg a b c) ;; (a b mid c) ;; (a b c end))