0
votes

Define a function contains that takes two parameters, a symbol A and a list of symbols L, and returns t only if L contains A as one of its elements.

That is the original question. I am very new to LISP and would like some code along with an explanation of the syntax. Coming from a java and C++ background LISP is very different in nature. Please help.

So far my code successfully takes two inputs as an parameter.

Pseudocode: I compare the value in A with the first Value of the List then pass the list and variable A back into the function with a recursive call until the the List is empty. If the List is empty return null.

The issue with this is if List contains the a nested List how do i recognize the nested loop.

Such as: (contains #\b '(a (((b))) c)) -> must print true.

So Far What I Have Code:

(defun contains (a list)
    (if (eq a(car list))
        (princ "t")
        (contains a (cdr list))))

(contains  #\B '(B a c d e f g))

I need a way for detecting at the end of the list. And a way to search inside nested lists.

1
I assume you're not allowed to use the standard MEMBER function? - Barmar
The question doesn't require you to go into nested lists. - Barmar
Unfortunatly no, I am only allowed to use Primitive function such as defun, car cdr cons if - user1046935
The problem definition says that L is a list of symbols. (a (((b))) c) is not a list of symbols, it's a list of a symbol, a list, and another symbol. - Barmar
That is an example list. The function is too also scan nested Lists for the variable then jump back out to the outer list and continue scanning the outer List. It must scan any and all nested Lists also. - user1046935

1 Answers

2
votes

First of all let's fix some your mistakes: #\b isn't a SYMBOL, it's a CHARACTER, as I understand we looking for symbol in a list of symbols, so we don't need to do some character -> symbol conversion. Second: don't (princ t) just return t.

My short variant:

(defun contains (sym nested-list)
  "Find if NESTED-LIST contains a SYM"
  ;; Check if our list is CONS-cell?.
  (if (consp nested-list)
    ;; Recursion on cars and cdrs
    (or (contains sym (car nested-list))
        (contains sym (cdr nested-list)))
    ;; Elseway just check for equality
    (eq sym nested-list)))

CL-USER> (contains 'a '(b c (x b y (f a)) d))
T
CL-USER> (contains 'w '(b c (x b y (f a)) d))
NIL

On your test-case too:

CL-USER> (contains 'b '(a (((b))) c))
T