user1722962
user1722962

Reputation: 79

working with lisp functions

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

Answers (2)

Will Ness
Will Ness

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

Net4All
Net4All

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

Related Questions