Reputation: 11
I am currently tackling some beginner Lisp problems. I am using Common Lisp.
Below I have tried to implement a basic find and replace: char1 is the character to search for in the list, char2 is the character to replace it with and list-to-search is the list I am searching through.
(defun find-and-replace (char1 char2 list-to-search &optional (ammended-list(list)))
(cond
((null list-to-search) ammended-list)
((eql char1 (car list-to-search))
(append ammended-list (list char2))
(find-and-replace char1 char2 (cdr list-to-search)))
(t (append ammended-list
(list (car list-to-search))
(find-and-replace char1 char2 (cdr list-to-search))))))
When I run:
(find-and-replace '1 'z '(1 2 3 1 4 5)) => (2 3 4 5)
Where as I would expect:
(z 2 3 z 4 5)
Upvotes: 0
Views: 699
Reputation: 781096
append
doesn't modify the argument list, you need to assign the result back to the variable. And you're not passing the amended list when you make the recursive calls, so it always uses the initial value nil
.
(defun find-and-replace (char1 char2 list-to-search &optional (ammended-list(list)))
(cond
((null list-to-search) ammended-list)
((eql char1 (car list-to-search))
(setq ammended-list (append ammended-list (list char2))
(find-and-replace char1 char2 (cdr list-to-search) ammended-list))
(t (setq ammended-list (append ammended-list (list char1))
(find-and-replace char1 char2 (cdr list-to-search) ammended-list))))
This isn't the best way to write the function, though. APPEND
is an expensive operation, it has to copy the list each time. Better is to build the new list one element at a time:
(defun find-and-replace(char1 char2 list-to-search)
(cond ((null list-to-search) nil)
((eql char1 (car list-to-search))
(cons char2 (find-and-replace char1 char2 (cdr list-to-search))))
(t (cons (car list-to-search) (find-and-replace char1 char2 (cdr list-to-search))))))
Upvotes: 2
Reputation: 139261
Issues:
1
is a number. z
is a symbol. Your code has nothing to do with characters, which are an actual datatype in Common Lisp.
Without proper formatting and indentation, Lisp programming gets extremely difficult.
The function append
has no side effects.
append
should be avoid, since it is expensive.
The lists your function can work with, are limited in length by the stack size due to the use of recursion. Typically on might use mapcar
instead.
Upvotes: 4