-1

I am new to lisp and I have a problem, I'm trying to find the number in the list but it is not working. I haven't made the return statement yet

(defun num (x 'y)
    (if (member x '(y)) 't nil))

(write (num 10 '(5 10 15 20)))

My output just outputs the nil instead of doing the function and I'm confused of what I am doing wrong.

sds
  • 58,617
  • 29
  • 161
  • 278
Panzer
  • 1
  • 2

3 Answers3

5

Solution

(defun member-p (element list)
  "Return T if the object is present in the list"
  (not (null (member element list))))

The not/null pattern is equivalent to (if (member element list) t nil) but is more common.

In fact, you do not really need this separate function, member is good enough.

The -p suffix stands for predicate, cf. integerp and upper-case-p.

Your code

  1. You cannot quote lambda list elements, so you need to replace defun num (x 'y) with defun num (x y)
  2. You need not quote t
  3. Quoting '(y) makes no sense, replace it with y.
  4. You do not need to write the function call, the REPL will do it for you.

See also

sds
  • 58,617
  • 29
  • 161
  • 278
2

You are almost certainly expected to not just use member, but to write a function which does what you need (obviously in real life you would just use member because that's what it's for).

So. To know if an object is in a list:

  • if the list is empty it's not;
  • if the head of the list is equal to the object it is;
  • otherwise it is in the list if it's in the tail of the list.

And you turn this into a function very straightforwardly:

(defun num-in-list-p (n l)
  ;; is N in L: N is assumed to be a number, L a list of numbers
  (cond ((null l)
         nil)
        ((= n (first l))
         t)
        (t
         (num-in-list-p n (rest l)))))
1

You could use the built in position function which will return the index of the number if it is in the list:

(position 1 '(5 4 3 2 1))

If you want to define your own function:

CL-USER> (defun our-member(obj lst)
   (if(zerop (length lst))
      nil
      (if(equal(car lst)obj)
      T
     (our-member obj (cdr lst)))))
OUR-MEMBER
CL-USER> (our-member 1 '(5 4 3 2 1))
T
CL-USER> (our-member 99 '(1 2 3 4 5))
NIL

We can create a function called "our-member" that will take an object (in your case a number) and a list (in your case a list of numbers) as an argument. In this situation our "base-case" will be whether or not the length of the list is equal to zero. If it is and we still haven't found a match, we will return nil. Otherwise, we will check to see if the car of the list (the first element in the list) is equal to the obj that we passed. If so, we will return T (true). However, if it is not, we will call the function again passing the object and the cdr of the list (everything after the car of the list) to the function again, until there are no items left within the list. As you can see, The first example of a call to this function returns T, and the second example call returns NIL.

What makes this utility function a good example is that it essentially shows you the under workings of the member function as well and what is going on inside.

Simeon Ikudabo
  • 2,152
  • 1
  • 10
  • 27