format
generates a string, but it doesn't do anything with it. You probably want to pass the result of format
on to something that does:
(defun mt ()
(dotimes (x 20)
(dotimes (y 20)
(insert (format "%3d " (* (1+ x) (1+ y)))))
(insert (format "\n"))))
UPDATE
I think you're also confused about how dotimes
works. From the doc string:
(dotimes (VAR COUNT [RESULT]) BODY...)
:around advice: ‘cl--wrap-in-nil-block’
Loop a certain number of times.
Evaluate BODY with VAR bound to successive integers running from 0,
inclusive, to COUNT, exclusive. Then evaluate RESULT to get
the return value (nil if RESULT is omitted).
Without a results
argument, dotimes
will only produce side-effects (modifying variables or state) if you explicitly tell it to, as I have above by adding the insert
forms. If you add a results
argument, you can use that variable to return a value.
To get the behaviour you expect, we need to add result
and some code to modify it:
(defun mt ()
(let ((res ""))
(dotimes (x 20 res)
(dotimes (y 20)
(setq res
(concat res (format "%3d " (* (1+ x) (1+ y))))))
(setq res
(concat res (format "\n"))))))
This form will return the table you have constructed, which you can then do what you like with.
(format "%..." ...)
is equivalent to Common Lisp(format nil "%..." ...)
. See also (elisp) Output Streams and (elisp) Output Functions