Pedro Delfino
Pedro Delfino

Reputation: 2681

Why inserting `format` function inside a `dolist` expression does not work in Common Lisp?

I am using SBCL, Eamcs, and Slime. Using the print function, I can do:

CL-USER> (dolist (item '(1 2 3))
           (print item))
1 
2 
3 
NIL

In addition, format function works for single elements:

CL-USER> (format nil "~a" 1)
"1"

Why the following insertion of format function inside dolist does not work?

CL-USER> (dolist (item '(1 2 3))
           (format nil "~a" item))
NIL

I was expecting to see all elements of the list processed by the format function.

Thanks

Upvotes: 0

Views: 104

Answers (3)

Ehvince
Ehvince

Reputation: 18375

Here DOLIST prints a list of numbers and returns NIL (because by default DOLIST returns NIL).

(dolist (item '(1 2 3))
    (print item))

format nil … creates a string. But DOLIST returns NIL, so you see nothing.

You can format t … to standard output, you can return values with DOLIST with return, but it returns and exits the loop (so it won't process every element).

You can use LOOP with collect to return something:

(loop for item in '(1 2 3)
    collect (format nil "~a" item))
("1" "2" "3")

using do wouldn't print nor return anything either.

Upvotes: 2

ignis volens
ignis volens

Reputation: 9252

The answer to this is that the first argument to format denotes a destination for the formatted output. It may be one of four things:

  • a stream, to which output goes;
  • t which denotes the value of the *standard-output* stream;
  • nil which causes format to return the formatted output rather than print it;
  • or a string with a fill pointer, which will append the output to the string at the fill pointer.

So (format nil ...) does not print anything: it returns something.

Upvotes: 4

Pedro Delfino
Pedro Delfino

Reputation: 2681

It is necessary to do a minor tweak on the format function to have the same result:

CL-USER> (dolist (item '(1 2 3))
           (format t "~a ~%" item))
1 
2 
3 
NIL

Upvotes: 0

Related Questions