This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

Writing my own member function

7 posts · 6806 views

Hey everyone. I'm brand new to Lisp. Any help that anyone can provide would be appreciated.

I'd like to write my own 'member' function that performs exactly the same as the built-in 'member' function. Any tips on how to go about doing this, or some code that can get me started?

Re: Writing my own member function

Have you in mind normal functions or CLOS methods?
For overriding of an ordinary function look at conduits.
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version). Temporary mirrors of aferomentioned: CLHS and a dark version.

Re: Writing my own member function

Thanks for the reply. I want normal functions.

I wrote something up last night, but it doesn't function completely properly.
(defun member (iTerm iList)
	(cond ((null iList) nil)
		  ((equal iTerm (car iList)) iList)
		  (t (member iTerm (cdr iList)))
	)
)
But returning from the following calls does not yield a proper result
(member 1  1)    ; should return 1, but returns that 1 is invalid argument
(member 1  '(( 0 1 2 3) 9 1 5))   ;should return (1 2 3) 9 1 5 but currently only returns 1 5

Re: Writing my own member function

Sorry, I misconceived your original post. Your implementation works in the same way as cl:member, but you obviously want a different behaviour. In the first example you didn't pass a list in which should be the item finded (but you want to compare atoms too?), in the second one you want recursive behaviour (not trivial, because you rather want a graphical tail of nested lists than a tail in a recursive manner).
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version). Temporary mirrors of aferomentioned: CLHS and a dark version.

Re: Writing my own member function

Optimus wrote: ...
(member 1  1)    ; should return 1, but returns that 1 is invalid argument
(member 1  '(( 0 1 2 3) 9 1 5))   ;should return (1 2 3) 9 1 5 but currently only returns 1 5
The built in member function will result in an error if the second argument is not a list. (error message "*** - member: A proper list must not end with 1" in CLISP)
member does only traverse the list not lists within it. 1 is compared to (0 1 2 3), 9 and 1 and returns (1 5). That the first element happens to have a 1 in it's structure is irrelevant.

You should correct your tests as the implementation is correct :)
I'm the author of two useless languages that uses BF as target machine.
Currently I'm planning a Scheme compiler :p

Re: Writing my own member function

I see. So I guess I want a modified function that will return my desired result for:
(member 1  '(( 0 1 2 3) 9 1 5))   ;should return (1 2 3) 9 1 5 but currently only returns 1 5
My current code, which was revised to compare atoms as well, is provided below.
(defun member (iTerm iValues) ; S is search term, L is list
	(cond ((null iValues) nil)
		  ((equal iTerm iValues) iValues)
		  ((equal iTerm (car iValues)) iValues)
		  ((member iTerm (cdr iValues)))
	)
)
Goheeca, your last comment about graphical tail of nested lists went over my head.

Re: Writing my own member function

OK, this function provides the desired functionality, but I don't know what is it good for? Why do you need such a function? Is it some kind of exercise?
(defun my-member (term list)
  (cond ((atom list) (when (equalp term list) term))
        ((null list) nil)
        ((and (listp (car list))
              (my-member term (car list)))
         (cons (my-member term (car list))
               (cdr list)))
        ((equalp term (car list)) list)
        (t (my-member term (cdr list)))))
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version). Temporary mirrors of aferomentioned: CLHS and a dark version.