category
category

Reputation: 2155

lisp iterative function always returns nil

this function is supposed to count the number of times that the element 'a' appears in a list, but is not working:

(defun iter-a_count (lst)
   (let ((count 0))
        (dolist (x lst)
                (if (equal x 'a) 
                    (setf count (+ count 1)))
         count )))

This function always returns nil. May I ask where I am going wrong?

Upvotes: 1

Views: 270

Answers (2)

npostavs
npostavs

Reputation: 5027

May I ask where I am going wrong?

Indentation (as in, you are indenting wrongly): you wrote

(defun iter-a_count (lst)
  (let ((count 0))
    (dolist (x lst)
      (if (equal x 'a) 
          (setf count (+ count 1)))
      count)))

But I think you meant

(defun iter-a_count (lst)
  (let ((count 0))
    (dolist (x lst)
      (if (equal x 'a) 
          (setf count (+ count 1))))
    count))

Upvotes: 2

user797257
user797257

Reputation:

The value returned from dolist macro is the third "argument" to it, i.e.

(dolist (iterator iterable result) forms)

Where iterator is updated every iteration to be the car of next cell of iterable, after all list cells have been visited, result is returned.

You didn't specify the result, and the default value for result is nil. I'm not sure what the purpose of count in the last line is - perhaps you wanted to return the count - in which case, put it after lst.

Several more things you want to consider:

(setf x (+ x 1))

is equivalent to:

(setf x (1+ x))

which is equivalent to:

(incf x)

It is more idiomatic to write

(when x forms)

instead of

(if x true-branch)

Because if you will later want to add more expressions to the true-branch, you will have to wrap them in progn - and that just clutters the code.

Also, what you are doing (or seem to be doing), can be replaced by a call to count-if with a proper predicate.

(defun count-a (list)
  (count-if #'(lambda (x) (equal x 'a)) list))

(count-a '(a b c d a b a d a c b d e))  ; 4

Upvotes: 5

Related Questions