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.

Drew
  • 75,699
  • 9
  • 109
  • 225
  • @gigiair Oh ok. I will check on that. – Benjamin Philip Nov 18 '20 at 08:55
  • 1
    Does this answer your question? [Functions print outputs twice the expected output](https://emacs.stackexchange.com/questions/18293/functions-print-outputs-twice-the-expected-output) – Drew Nov 18 '20 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 '20 at 23:42
  • Thank you I get what you mean – Benjamin Philip Nov 19 '20 at 01:50

2 Answers2

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.

Fran Burstall
  • 3,665
  • 10
  • 18
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.

gigiair
  • 2,124
  • 1
  • 8
  • 14