Reputation: 79
I am trying to write a function that returns a list of atoms in a list,lets say i have a list which has both atoms and a list in it and when I run the function it should return a list of atoms inside..
For example:
(func '(2 34 5 (12) 7 (A B C) +))
-> (2 34 7 +)
And I want to try if the arguments inside the result are true such that when I run:
(ATOM ( (func '(2 34 5 (12) 7 (A B C) +)) )
->T
Any ideas on how I can go about it? Books or references?
Upvotes: 2
Views: 139
Reputation: 71070
Using standard CL functions,
[3]> (remove-if-not #'atom '(1 2 (12) +))
(1 2 +)
[6]> (every #'atom (remove-if-not #'atom '(1 2 (12) +)))
T
If you want to write them yourself, you can fuse the #'atom
in and make two specialized functions, say remove-atoms
and every-is-atom
. But "atom" is a name of a built-in function atom
.
One way to write the first is
(defun remove-atoms (xs &aux (ys (list 1)))
(let ((p ys))
(dolist (x xs (cdr ys))
(if (atom x) (setf (cdr p) (list x) p (cdr p))))))
This builds the result list in a top-down manner using destructive update, which doesn't violate the spirit of functional programming here because it is used locally, as an implementation technique. This can be seen as a Common-LISP–specific translation of the general functional tail-recursive-modulo-cons code from the other answer.
And the second function:
(defun every-is-atom (xs)
(dolist (x xs T)
(if (not (atom x))
(return-from every-is-atom NIL))))
Upvotes: 3
Reputation: 21
So you want a function that only returns the atomic values that exist in the list passed as an argument?
Like this?
(defun func (lst)
(cond
((null lst) '())
((atom (first lst))
(cons (first lst) (func (rest lst))))
(t (func (rest lst)))))
Not for Common lisp specifically, but still a good read in my opinion: SICP
Upvotes: 2