## Mapping functions

The procedures `string-for-each` and `string-map` are documented under Strings.

The procedure `string-cursor-for-each` is documented under String Cursor API.

Procedure: `map` ``proc`` `sequence``1` `sequence``2` `...`

Procedure: `for-each` ``proc`` `sequence``1` `sequence``2` `...`

> The `map` procedure applies `proc` element-wise to the elements of the `sequence`s and returns a list of the results, in order. The dynamic order in which `proc` is applied to the elements of the `sequence`s is unspecified.

> The `for-each` procedure does the same, but is executed for the side-effects of `proc`, whose result (if any) is discarded. Unlike `map`, `for-each` is guaranteed to call `proc` on the elements of the `sequences`s in order from the first element(s) to the last. The value returned by `for-each` is the void value.

> Each `sequence` must be a generalized sequence. (Traditionally, these arguments were restricted to lists, but Kawa allows sequences, including vectors, Java arrays, and strings.) If more than one `sequence` is given and not all `sequence`s have the same length, the procedure terminates when the shortest `sequence` runs out. The `sequence`s can be infinite (for example circular lists), but it is an error if all of them are infinite.

> The `proc` must be a procedure that accepts as many arguments as there are `sequence` arguments. It is an error for `proc` to mutate any of the `sequence`s. In the case of `map`, `proc` must return a single value.

>     (map cadr '((a b) (d e) (g h)))
>         ⇒ (b e h)

>     (map (lambda (n) (expt n n))
>          '(1 2 3 4 5))
>         ⇒ (1 4 27 256 3125)

>     (map + ’(1 2 3) ’(4 5 6 7))  ⇒ (5 7 9)

>     (let ((count 0))
>       (map (lambda (ignored)
>              (set! count (+ count 1))
>              count)
>            '(a b)))
>         ⇒ (1 2) or (2 1)

> The result of `map` is a list, even if the arguments are non-lists:

>     (map +
>          #(3 4 5)
>          (float[] 0.5 1.5))
>         ⇒ (3.5 5.5)

> To get a vector result, use `vector-map`.

>     (let ((v (make-vector 5)))
>       (for-each (lambda (i)
>                   (vector-set! v i (* i i)))
>                 '(0 1 2 3 4))
>       v)
>         ⇒  #(0 1 4 9 16)

> A string is considered a sequence of `character` values (not 16-bit `char` values):

>     (let ((v (make-vector 10 #\-)))
>       (for-each (lambda (i ch)
>                   (vector-set! v i ch))
>                 [0 <: ]
>                 "Smile 😃!")
>        v)
>         ⇒ #(#\S #\m #\i #\l #\e #\space #\x1f603 #\! #\- #\-)

> Performance note: These procedures are pretty well optimized. For each `sequence` the compiler will by default create an iterator. However, if the type of the `sequence` is known, the compiler will inline the iteration code.

Procedure: `vector-map` ``proc`` ``sequence```1` ``sequence```2` `…`

> Same as the `map` procedure, except the result is a vector. (Traditionally, these arguments were restricted to vectors, but Kawa allows sequences, including lists, Java arrays, and strings.)

>     (vector-map cadr '#((a b) (d e) (g h)))
>         ⇒ #(b e h)

>     (vector-map (lambda (n) (expt n n))
>                 '#(1 2 3 4 5))
>         ⇒ #(1 4 27 256 3125)

>     (vector-map + '#(1 2 3) ’#(4 5 6 7))
>         ⇒ #(5 7 9)

>     (let ((count 0))
>       (vector-map
>         (lambda (ignored)
>           (set! count (+ count 1))
>           count)
>         '#(a b)))
>         ⇒ #(1 2) or #(2 1)

Procedure: `vector-for-each` ``proc`` ``vector```1` ``vector```2` `…`

> Mostly the same as `for-each`, however the arguments should be generalized vectors. Specifically, they should implement `java.util.List` (which both regular vectors and uniform vectors do). The `vectors` should also be efficiently indexable.

> (Traditionally, these arguments were restricted to vectors, but Kawa allows sequences, including lists, Java arrays, and strings.)

>     (let ((v (make-list 5)))
>       (vector-for-each
>         (lambda (i) (list-set! v i (* i i)))
>         '#(0 1 2 3 4))
>       v)
>         ⇒ (0 1 4 9 16)