It is often useful to apply a pointwise operation to two or more arrays in a many-to-one manner. Library support for this, which math/array provides, is called broadcasting.

Creating a 6×6 identity matrix:
> (define diag (diagonal-array 2 6 1 0))
> (array-shape diag)

- : Indexes

'#(6 6)

> diag

- : (Array (U One Zero))

 (array #[#[1 0 0 0 0 0] #[0 1 0 0 0 0] #[0 0 1 0 0 0] #[0 0 0 1 0 0] #[0 0 0 0 1 0] #[0 0 0 0 0 1]])
Multiplying each element by 10:
> (array-shape (array 10))

- : Indexes

'#()

> (array* diag (array 10))

- : (Array Index)

 (array #[#[10 0 0 0 0 0] #[0 10 0 0 0 0] #[0 0 10 0 0 0] #[0 0 0 10 0 0] #[0 0 0 0 10 0] #[0 0 0 0 0 10]])
Adding (array #[0 1 2 3 4 5]) pointwise to every row:
 > (array+ (array* diag (array 10)) (array #[0 1 2 3 4 5]))

- : (Array Nonnegative-Fixnum)

 (array #[#[10 1 2 3 4 5] #[0 11 2 3 4 5] #[0 1 12 3 4 5] #[0 1 2 13 4 5] #[0 1 2 3 14 5] #[0 1 2 3 4 15]])

Suppose we have two array shapes ds = (vector d0 d1 ...) and es = (vector e0 e1 ...). Broadcasting proceeds as follows:
1. The shorter shape is padded on the left with 1 until it is the same length as the longer shape.

2. For each axis k, dk and ek are compared. If dk = ek, the result axis is dk; if one axis is length 1, the result axis is the length of the other; otherwise fail.

3. Both arrays’ axes are stretched by (conceptually) copying the rows of axes with length 1.

Example: Suppose we have an array drr with shape ds = #(4 1 3) and another array err with shape es = #(3 3). Following the rules:
1. es is padded to get #(1 3 3).

2. The result axis is derived from #(4 1 3) and #(1 3 3) to get #(4 3 3).

3. drr’s second axis is stretched to length 3, and err’s new first axis (which is length 1 by rule 1) is stretched to length 4.

The same example, but more concrete:
 > (define drr (array #[#[#["00" "01" "02"]] #[#["10" "11" "12"]] #[#["20" "21" "22"]] #[#["30" "31" "32"]]]))
> (array-shape drr)

- : Indexes

'#(4 1 3)

 > (define err (array #[#["aa" "ab" "ac"] #["ba" "bb" "bc"] #["ca" "cb" "cc"]]))
> (array-shape err)

- : Indexes

'#(3 3)

> (define drr+err (array-map string-append drr err))
> (array-shape drr+err)

- : Indexes

'#(4 3 3)

> drr+err

- : (Array String)

 (array #[#[#["00aa" "01ab" "02ac"] #["00ba" "01bb" "02bc"] #["00ca" "01cb" "02cc"]] #[#["10aa" "11ab" "12ac"] #["10ba" "11bb" "12bc"] #["10ca" "11cb" "12cc"]] #[#["20aa" "21ab" "22ac"] #["20ba" "21bb" "22bc"] #["20ca" "21cb" "22cc"]] #[#["30aa" "31ab" "32ac"] #["30ba" "31bb" "32bc"] #["30ca" "31cb" "32cc"]]])
Notice how the row #["00" "01" "02"] in drr is repeated in the result because drr’s second axis was stretched during broadcasting. Also, the column #[#["aa"] #["ba"] #["ca"]] in err is repeated because err’s first axis was stretched.

For the above example, array-map does this before operating on drr and err:
 > (define ds (array-shape-broadcast (list (array-shape drr) (array-shape err))))
> ds

- : Indexes

'#(4 3 3)

- : (Array String)

 (array #[#[#["00" "01" "02"] #["00" "01" "02"] #["00" "01" "02"]] #[#["10" "11" "12"] #["10" "11" "12"] #["10" "11" "12"]] #[#["20" "21" "22"] #["20" "21" "22"] #["20" "21" "22"]] #[#["30" "31" "32"] #["30" "31" "32"] #["30" "31" "32"]]])

- : (Array String)

 (array #[#[#["aa" "ab" "ac"] #["ba" "bb" "bc"] #["ca" "cb" "cc"]] #[#["aa" "ab" "ac"] #["ba" "bb" "bc"] #["ca" "cb" "cc"]] #[#["aa" "ab" "ac"] #["ba" "bb" "bc"] #["ca" "cb" "cc"]] #[#["aa" "ab" "ac"] #["ba" "bb" "bc"] #["ca" "cb" "cc"]]])

The parameter array-broadcasting controls how pointwise operations broadcast arrays. Its default value is #t, which means that broadcasting proceeds as described in Broadcasting Rules. Another possible value is #f, which allows pointwise operations to succeed only if array shapes match exactly:
 > (parameterize ([array-broadcasting #f]) (array* (index-array #(3 3)) (array 10)))

Another option is R-style permissive broadcasting, which allows pointwise operations to always succeed, by repeating shorter axes’ rows instead of repeating just singleton axes’ rows:
> (define arr10 (array-map number->string (index-array #(10))))
> (define arr3 (array-map number->string (index-array #(3))))
> arr10

- : (Array String)

(array #["0" "1" "2" "3" "4" "5" "6" "7" "8" "9"])

> arr3

- : (Array String)

(array #["0" "1" "2"])

> (array-map string-append arr10 (array #["+" "-"]) arr3)