Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differentiate between a list and an atom in common lisp

I have a basic clisp function that I am making that just returns the number of atoms in a list. The issue I am having is I need it to increment for atoms in a list that is in the list, instead of seeing a list as 1 element in the list.

The real question I guess is how do you differentiate in your code whether an element is a list or an atom? If I can do that, I can send the lists to another function to add up and return the number of atoms they contain.

Clear as mud? :)

I have an example here:

(defun list_length (a)
  (cond ((null a) 0)
        (t (+ 1 (list_length (cdr a))))))

This works great if there are no embedded lists in the parent list, for example, '(1 2 3 (4 5) 6) would return 5. I need it to include 4 and 5 instead of the list (4 5) as one.

Thanks for your help.

Jon


EDIT:

(defun list_length (a)
  (cond ((null a) 0)
        ((listp (car a)) (list_length (car a)))
        (t (+ 1 (list_length (cdr a))))))

[18]> (list_length '(1 2 3 (4 5) 6))
1. Trace: (LIST_LENGTH '(1 2 3 (4 5) 6))
2. Trace: (LIST_LENGTH '(2 3 (4 5) 6))
3. Trace: (LIST_LENGTH '(3 (4 5) 6))
4. Trace: (LIST_LENGTH '((4 5) 6))
5. Trace: (LIST_LENGTH '(4 5))
6. Trace: (LIST_LENGTH '(5))
7. Trace: (LIST_LENGTH 'NIL)
7. Trace: LIST_LENGTH ==> 0
6. Trace: LIST_LENGTH ==> 1
5. Trace: LIST_LENGTH ==> 2
4. Trace: LIST_LENGTH ==> 2
3. Trace: LIST_LENGTH ==> 3
2. Trace: LIST_LENGTH ==> 4
1. Trace: LIST_LENGTH ==> 5
5
[19]> (dribble)
like image 958
jmd4931 Avatar asked Nov 05 '10 00:11

jmd4931


People also ask

What does list mean in Lisp?

Lists are single linked lists. In LISP, lists are constructed as a chain of a simple record structure named cons linked together.

Is a number an atom in Lisp?

Basic Building Blocks in LISPAn atom is a number or string of contiguous characters. It includes numbers and special characters. A list is a sequence of atoms and/or other lists enclosed in parentheses. A string is a group of characters enclosed in double quotation marks.

Is everything a list in Lisp?

Lisp has one: everything is a list. The first element is a function name, and the rest are its arguments. Thus, the language is simply a collection of compile- and run-time functions, trivially extensible.

What is a dot in a list in Lisp?

Lists are built up from smaller pieces in Lisp. The dot notation indicates those smaller pieces.


2 Answers

(listp foo) will return t if foo is a list and nil otherwise.

So you can make your list_length function handle nested lists by adding the following case to your cond:

((listp (car a)) (+ (list_length (car a)) (list_length (cdr a))))
like image 184
sepp2k Avatar answered Sep 30 '22 16:09

sepp2k


ATOM is the predicate you are asking for.

I recommend using FLATTEN, a standard routine to flatten lists in lists - I present one implementation here.

(defun flatten (x)
  "descend into the supplied list until an atom is hit.
append the atom to the flattened rest"
  (if (endp x)
      x
    (if (atom (car x ))
    (append (list (car x)) (flatten (cdr x)))
      (append (flatten (car x)) (flatten (cdr x ))))))

Flatten returns a list: you can run LENGTH on the list to see how many ATOMS you wound up with.

like image 23
Paul Nathan Avatar answered Sep 30 '22 15:09

Paul Nathan