feilong <coli.uni-sb.de at feilong> writes:
> Hallo,
> It is strange for me. What is difference between :(apply #'mapcar fn1
> (mapcar fn2 list)) and (mapcar fn1 (mapcar fn2 list))
> For example:
> 12. Break [13]> (apply #'mapcar #'list (mapcar #'cdr '((1 2 3) (a b c)
> (e d f))))
> ((2 B D) (3 C F))
>
> 13. Break [14]> (mapcar #'list (mapcar #'cdr '((1 2 3) (a b c) (e d f))))
> (((2 3)) ((B C)) ((D F)))
>
> Why do these 2 applications return different results? What roles does
> "apply" here play? Is it permitted that 2 funktions (#'mapcar and
> #'cdr ) follow "apply"?
>
> Thank you
> Greetings
> Xu
>
The inner call to MAPCAR results in _one_ list with _three_ elements:
* (mapcar #'cdr '((1 2 3) (a b c) (e d f)))
((2 3) (B C) (D F))
So
* (mapcar #'list (mapcar #'cdr '((1 2 3) (a b c) (e d f))))
(((2 3)) ((B C)) ((D F)))
is like
* (mapcar #'list '((2 3) (b c) (d f)))
(((2 3)) ((B C)) ((D F)))
i.e. the result is obtained like this:
* (list (list '(2 3)) (list '(b c)) (list '(d f)))
(((2 3)) ((B C)) ((D F)))
(where the outermost invocation of LIST is always there with MAPCAR
while the three innermost invocations resulted in your providing
#'LIST as the first argument to MAPCAR).
Now,
* (apply #'mapcar #'list (mapcar #'cdr '((1 2 3) (a b c) (e d f))))
((2 B D) (3 C F))
is the same as
* (apply #'mapcar #'list '((2 3) (b c) (d f)))
((2 B D) (3 C F))
which is equivalent to the call
* (mapcar #'list '(2 3) '(b c) '(d f))
((2 B D) (3 C F))
and is obtained like:
* (list (list 2 'b 'd) (list 3 'c 'f))
((2 B D) (3 C F))
i.e. LIST is first called with the first element of each of the three
lists and then again with the second element of each list.
I think what confused you is that the last argument to APPLY is
spread - see the CLHS entry for APPLY and specifically the glossary
entry for 'spreadable argument list designators' at
<http://www.lispworks.com/reference/HyperSpec/Body/26_glo_s.htm#spreadable_argument_list_designator>.
Cheers,
Edi.