I am trying to learn Scheme and I am having a hard time understanding the difference between map
and apply
.
As I understand, map
applies the function to each element of the list, and apply
applies something to the arguments of a procedure.
Can they be used interchangeably?
Map is a built in Scheme function that takes a function and a list as an argument, and returns the list that results by applying that function to every element of the list.
The other constructor, cons , is used when you already have a list and you want to add one new element. Cons takes two arguments, an element and a list (in that order), and returns a new list whose car is the first argument and whose cdr is the second.
The append function joins two lists together to make one. The append function is built into Scheme. It concatenates two lists, that is to say, given two lists list1 and list2 it produces a new list which starts with the same elements as list1 and finishes with those of list2 .
They are not the same! Their names can actually help remember which does what.
map
will take as argument one procedure and one or more lists. The procedure will be called once for each position of the lists, using as arguments the list of elements at that position:
(map - '(2 3 4)) ; => (-2 -3 -4)
map
called (- 2)
, (- 3)
, (- 4)
to build the list.
(map + '( 1 2 3) '(10 20 30)) ; => (11 22 33)
map
called (+ 1 10)
(+ 2 20)
(+ 3 30)
to build the list.
(map * '(2 2 -1) '(0 3 4) '(5 4 2)) ; => (0 24 -8)
map
called (* 2 0 5)
(* 2 3 4)
(* -1 4 2)
to build the list.
map
has that name because it implements a "map" (function) on a set of values (in the lists):
(map - '(2 3 4)) arguments mapping "-" result 2 === (- 2) ===> -2 3 === (- 3) ===> -3 4 === (- 4) ===> -4 (map + '( 1 2 3) '(10 20 30)) arguments mapping "+" result 1 10 === (+ 1 10) ===> 11 2 20 === (+ 2 20) ===> 22 3 30 === (+ 3 30) ===> 33
apply
will take at least two arguments, the first of them being a procedure and the last a list. It will call the procedure with the following arguments, including those inside the list:
(apply + '(2 3 4)) ; => 9
This is the same as (+ 2 3 4)
(apply display '("Hello, world!")) ; does not return a value, but prints "Hello, world!"
This is the same as (display "Hello, world!")
.
apply
is useful when you have arguments as a list,
(define arguments '(10 50 100)) (apply + arguments)
If you try to rewrite the last line without using apply
, you'll realize that you need to loop over the list summing each element...
apply
may also be used with more than those two arguments. The first argument must be a callable object (a procedure or a continuation). The last one must be a list. The others (between the first and the last) are objects of any type. So calling
(apply PROC a b c ... y z '(one two ... twenty))
is the same as calling
(PROC a b c ... y z one two ... twenty)
Here's a concrete example:
(apply + 1 -2 3 '(10 20)) ; => 32
This is the same as (+ 1 -2 3 10 20)
apply
has that name because it allows you to "apply" a procedure to several arguments.
No, apply
calls its first argument as a procedure, with all the rest as its arguments, with the last one -- list -- opened up, i.e. its contents "spliced in":
(apply f a b (list c d e)) == (f a b c d e)
E.g.:
(apply + 1 2 (list 3 4 5))
;Value:15
It is just one call; whereas map
is indeed calling its first argument for each member element of its second argument.
One combined use of map
and apply
is the famous transpose
trick:
(apply map list '((1 2 3) (10 20 30)))
;Value:((1 10) (2 20) (3 30))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With