Reputation: 13
I am trying to learn common lisp through paradigms of artificial intelligence. one of the exercises in the book was to define a function that would return the last name of a given list without a certain suffix or word. As an example if the list contained bruce banner, phd it would return banner. here is my solution, however this would still return the last element regardless if it was a suffix or not
(Defun last-name (name)
(if (member (last name) *suffix*)
(Last-name (butlast name))
(last name)))
where
(defparameter *suffix* '( MD PHD DR))
a similar exercise was presented in the book omitting a prefix in a list using 'rest' instead of 'butlast' and returning the first element. That worked perfectly fine.
(defparameter *titles* '( Mr MRS MS SIR MADAM DR ADMIRAL MAJOR GENRAL ))
(Defun first-name (name)
(if (member (first name) *titles*)
(first-name (rest name))
(first name)))
I am not sure if I am missing anything in the last-name function or if my logic is incorrect. Any help is greatly appreciated! Apologies if the text is long, it is my first post and I was not sure what level of detail I should include.
Thank you.
Upvotes: 1
Views: 1501
Reputation: 27424
The reason is that last
does not return the last element of a list, but a list containing the last element. That is:
(last '(bruce banner phd))
;; -> (PHD), not PHD
Actually, last
gets an optional argument n
after the list, argument which is set to 1 by default, and returns a list with the last n
elements of the first parameter (see the manual).
So the function member
does not return true.
Try to change the function in:
(defun last-name (name)
(if (member (car (last name)) *suffix*)
(Last-name (butlast name))
(car (last name))))
Upvotes: 2