Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Help with lisp function

13 views
Skip to first unread message

Todd Baker

unread,
Nov 16, 2003, 3:03:09 PM11/16/03
to
Hi Group I was wondering if anyone could answer a question for me I'm
having problems with the following 2 functions and was wondering if
anyone could help me understand what I'm doing wrong.

;this function works just fine
(defun atoms_help (mylist)
(cond ((null mylist) nil)
((atom mylist) (list mylist))
(t (append (atoms_help (first mylist))
(atoms_help (rest mylist))))))

;how ever for my class we are not allowed to use the cond predicate
and so
;i rewrote the function as follows but keep getting an error
(defun atoms_help(mylist)
(if (null mylist)()
(if (or (atom mylist) (list mylist))
(append (atoms_help (first mylist))
(atoms_help(rest mylist))))
)
)

if anyone could help i'd really appreciate it, thanks todd

Henrik Motakef

unread,
Nov 16, 2003, 3:48:49 PM11/16/03
to
bak...@hotmail.com (Todd Baker) writes:

> Hi Group I was wondering if anyone could answer a question for me I'm
> having problems with the following 2 functions and was wondering if
> anyone could help me understand what I'm doing wrong.

You don't format your code properly and choose suboptimal identifiers ;-)

Seriously, a direct translation of the first function to use IF only
instead of COND would be

(defun atoms-help (mylist)
(if (null mylist)
nil
(if (atom mylist)
(list mylist)
(append (atoms-help (first mylist))
(atoms-help (rest mylist))))))

Your use of OR in

| (if (or (atom mylist) (list mylist))
| (append (atoms_help (first mylist))
| (atoms_help(rest mylist))))))

will return the result of APPEND if either (atom mylist) or (list
mylist) are non-nil, which is always the case because (list mylist) is
never nil (i.e. an empty list). The only way to get nil through a call
to LIST is by not passing any arguments to it, as in (list).

I guess you should reconsider your idea of what OR does, and probably
IF as well.

Additionally, even if I don't think that you wanted to do that anyway,
using IF with only a then-clause, but no else, is usually considered
bad style. Either have an else-clause that returns nil implicitly if
this nil has an interesting meaning in your program, or use WHEN
instead of IF.

Pascal Bourguignon

unread,
Nov 16, 2003, 5:32:22 PM11/16/03
to
bak...@hotmail.com (Todd Baker) writes:

> Hi Group I was wondering if anyone could answer a question for me I'm
> having problems with the following 2 functions and was wondering if
> anyone could help me understand what I'm doing wrong.
>
> ;this function works just fine
> (defun atoms_help (mylist)
> (cond ((null mylist) nil)
> ((atom mylist) (list mylist))
> (t (append (atoms_help (first mylist))
> (atoms_help (rest mylist))))))
>
> ;how ever for my class we are not allowed to use the cond predicate
> and so
> ;i rewrote the function as follows but keep getting an error

Oh! If you're not allowed to use the cond predicate, then the correct
way to do it is:

(defmacro not-the-cond-predicate (&rest clauses)
(let ((ifs '()))
(dolist (clause (reverse clauses))
(setq ifs (append `(if ,(car clause) (progn ,@(cdr clause)) ,ifs))) )
ifs))

;; Note the indentation. Please use a lisp-aware editor!

(defun atoms_help (mylist)
(not-the-cond-predicate ((null mylist) nil)


((atom mylist) (list mylist))
(t (append (atoms_help (first mylist))
(atoms_help (rest mylist))))))

> (defun atoms_help(mylist)
> (if (null mylist)()
> (if (or (atom mylist) (list mylist))
> (append (atoms_help (first mylist))
> (atoms_help(rest mylist))))
> )
> )
>
> if anyone could help i'd really appreciate it, thanks todd

Then you can run:

(macroexpand (quote
(not-the-cond-predicate ((null mylist) nil)


((atom mylist) (list mylist))
(t (append (atoms_help (first mylist))
(atoms_help (rest mylist)))))

))

and compare with your version to see where the error lies...

--
__Pascal_Bourguignon__
http://www.informatimago.com/

Lowell Kirsh

unread,
Nov 16, 2003, 7:36:24 PM11/16/03
to
Usually cond is implemented as a macro that expands to a nested if
expression. So even simpler than writing a bunch of code yourself for
macroexpansion, just macroexpand the original cond.

the following :
(macroexpand-1 '(cond ((null mylist) nil)


((atom mylist) (list mylist))
(t (append (atoms_help (first mylist))
(atoms_help (rest mylist))))))

evaluates (in my lisp implementation) to :
(IF (NULL MYLIST) NIL
(IF (ATOM MYLIST) (LIST MYLIST)
(APPEND (ATOMS_HELP (FIRST MYLIST)) (ATOMS_HELP (REST MYLIST)))))

Lowell

0 new messages