1

Here is my function

(defun freq (symbol_A List_L)
    (cond ((atom (car List_L)) 
        (cond ((eq (car List_L) symbol_A) t (+ 1 (freq symbol_A (cdr List_L))))
            (t 0))) 
    (T (freq symbol_A (cdr List_L))))
)

I am getting an error variable ATOM has no value. Here is what I am testing with

(freq  'c '((a c) c e)) --> 2
(freq  'f '(((s) o ) d)) --> 0
(freq  'f '(((f) f) f f)) --> 4

Can not understand where is my error.

I also tried this:

(defun freq (a L)
  (cond
   ((null L) 0)
   ((equal a (car L)) (+ 1 (freq a (cdr L))))
   (t (freq a (cdr L)))))
Yaroslav Dukal
  • 3,894
  • 29
  • 36

2 Answers2

1

There is a syntax error in your code.

Indent and format your code

First you need to format your code:

(defun freq (A L)
  (cond (atom (car L))             ; first clause
        (eq A (car (car L )))      ; second clause
        (T (+ 1 (freq A (cdr L)))) ; third clause
        (T (freq A (cdr L)))))     ; fourth clause

A useful COND:

(cond ((> i 0) :positive)
      ((< i 0) :negative)
      (t       :equal))

You have written something like:

(cond (> i 0) :positive
      (< i 0) :negative
      (t      :equal))

Here a Lisp interpreter would complain that > has no value. It's because it is used as a variable. (> i 0) is seen as the first clause and the test form is the variable >. Since > usually is not a variable, this is an error.

A compiler might even reject the whole form at compile time, since there are clauses which are not lists.

As you can see the parentheses around a clause are missing in your code. Check the syntax of cond...

cond {clause}* => result*

A cond has zero or more clauses.

clause::= (test-form form*) 

Each clause is a list (!!) starting with a test-form and followed by zero or more forms.

It makes also no sense to have two clause with T as the test form. The first one will always be take and the second one will always be ignored.

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
1

Knowing that nil is an atom, you can simply recurse over the car and cdr of each cons cell. When you hit an atom, add 1 if it matches or 0 if it doesn't.

(defun freq (sym tree)
  (if (atom tree)
      (if (eq sym tree) 1 0)
      (+ (freq sym (car tree)) (freq sym (cdr tree)))))
uselpa
  • 18,732
  • 2
  • 34
  • 52