oracle
oracle

Reputation: 13

return the second to last list element in common lisp

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

Answers (1)

Renzo
Renzo

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

Related Questions