The Lisp function
G
is defined by:(defun g (l) (mapcon #'list l))
What is the result of evaluating the form
(apply #'append (mapcon #'g '(1 2)))
?
Justify the answer.
I've seen that mapcon
works with nconc
and cdr
, but the final answer will be (1 2 2 2)
and I don't know how to properly explain it. Please help.
First, let's call:
(mapcon (lambda (list) (print list) nil) '(1 2))
Because the anonymous function returns NIL all the time, the resulting list is NIL; the call prints this:
(1 2)
(2)
So in your example, when you call (mapcon #'g '(1 2))
, g
will be called first with (1 2)
, then with (2)
. Function g
returns a list, and mapcon
concatenates them.
What happens can be replicated in the REPL by computing each part explicitly:
USER> (mapcon #'list '(1 2))
((1 2) (2))
USER> (mapcon #'list '(2))
((2))
USER> (nconc ** *)
((1 2) (2) (2))
Finally, (apply #'append list-of-lists)
calls append
with a list of arguments.
The signature of append
is:
append &rest lists => result
Which means that if l1
, l2
and l3
are lists, the list that contains all their elements is:
(append l1 l2 l3)
Here the arguments to append
are stored in a list, so the way to pass an arbitrary list of arguments to a function is by using apply
. So that means (apply #'append lists)
concatenates all the lists in lists, which is why in your case the result is (1 2 2 2)
.
Note that using apply
is not recommended when the number of arguments is arbitrary (possibly large), since apply
is limited by CALL-ARGUMENTS-LIMIT
. One other possible way to do it is:
(loop for list in lists append list)