0

Let's say have the following list foo:

(setq foo '(cat dog rat bar))

When I iterate over it using say dolist, I get an extra nil:

(dolist (ele foo)
  (print ele))
cat

dog

rat

bar
nil

Why is there the extra nil ? Shouldn't dolist only iterate over the list the lenght times? (Over each element)

Of course having seen dotimes in the documentation along with dolist I tried to use that as well:

(dotimes (i (length foo))
  (print (nth i))))
cat

dog

rat

bar
nil

I also tried (- (length foo) 1)

cat

dog

rat
nil

So here are my questions

  1. Shouldn't nil be omitted in all cases?
  2. Is there a way I can omit that nil (and iterate over all elements)
  3. I have a feeling that this something to do with linked lists. Can you please explain the missing concept?

Note: I am quite new to elisp and lisp in general. Please be gentle while commenting and answering. I actually am iterating over an alist and accessing the keys and values using car and cdr.

4
  • @gigiair Oh ok. I will check on that. Nov 18, 2020 at 8:55
  • 1
    Does this answer your question? Functions print outputs twice the expected output
    – Drew
    Nov 18, 2020 at 23:40
  • It's due to your evaluating the dolist sexp interactively, and the command you use to do that first evaluates the sexp and then prints the result it returns. It has nothing to do with dolist itself or iteration.
    – Drew
    Nov 18, 2020 at 23:42
  • Thank you I get what you mean Nov 19, 2020 at 1:50

2 Answers 2

3

Welcome to SE Emacs. The nil you are seeing is not an extra iteration: it is simply the return value of the dolist or dotimes function.

2
  • Oh ok. Thank you. I didn't notice that in the docs. Nov 18, 2020 at 8:49
  • @BenjaminPhilip Every expression has a value, which is one important factor that makes Emacs Lisp simple.
    – xuchunyang
    Nov 18, 2020 at 10:03
1

The issue come because the print output stream and the eval output stream are the same. If you create a different output stream as the default one, the trouble diseapear.

(setq foo '(cat dog rat bar ))
  
(dolist (ele foo)
  (print ele (get-buffer-create "kill-me")))
 

The print is now int the "kill-me" buffer and the nil in the default output.buffer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.