Golo Roden
Golo Roden

Reputation: 150654

When would I use mapc instead of mapcar?

So far I have been using mapcar to apply a function to all elements of a list, such as:

(mapcar (lambda (x) (* x x))
        '(1 2 3 4 5))
;; => '(1 4 9 16 25)

Now I learned that there is also the mapc function which does exactly the same, but does not return a new list, but the original one:

(mapc (lambda (x) (* x x))
      '(1 2 3 4 5))
;; => '(1 2 3 4 5)

What's the intent of this function? When would I use mapc instead of mapcar if I am not able to access the result?

Upvotes: 7

Views: 2002

Answers (2)

Rainer Joswig
Rainer Joswig

Reputation: 139261

The Common Lisp Hyperspec says:

mapc is like mapcar except that the results of applying function are not accumulated. The list argument is returned.

So it is used when mapping is done for possible side-effects. mapcar could be used, but mapc reduces unnecessary consing. Also its return value is the original list, which could be used as input to another function.

Example:

(mapc #'delete-file (mapc #'compile-file '("foo.lisp" "bar.lisp")))

Above would first compile the source files and then delete the source files. Thus the compiled files would remain.

(mapc #'delete-file (mapcar #'compile-file '("foo.lisp" "bar.lisp")))

Above would first compile the source files and then delete the compiled files.

Upvotes: 17

Ben S
Ben S

Reputation: 1555

You should use mapc when you don't need to use the result of applying the function over the list. For example, to print out every element, you could use:

(mapc #'print '(1 2 3 4 5))

Technically, the print function will return something, but you don't need to use it, so you ignore it.

Upvotes: 4

Related Questions