TL;DR version:
Applying array broadcasting to mutable or non-strict arrays can be very difficult to reason about, so should one restrict broadcasting to strict, immutable arrays? or ignore the difficulties and learn to love array broadcasting because it's useful and can be efficient?
Some examples and questions follow.
I've been trying to understand how the features of array broadcasting, mutability, and non-strict arrays interact in math/array
, and how they might interact in other frameworks.
For example, one might make the bare call with explicit broadcasting
(define brr0 (array-broadcast arr0 ds))
or have a call with implicit broadcasting
(define brr1 (array-map * arr1 arr2 arr3))
where arr1
, arr2
, and arr3
are arrays with different, but compatible, shapes for broadcasting.
First, if brr0
is mutable (meaning that arr0
is mutable, which in math/array means arr0
is strict), then
(array-set! brr0 #(1 2) val)
may happen to change all entries of brr0
with first index 1, or second index 2, or change the values of all entries of brr0
entirely.
It is nearly impossible to reason about programs where this can happen, so perhaps broadcasting should be limited to immutable arrays.
In the second example, if arr1
, arr2
, or arr3
are broadcast, then the broadcast version is "consumed" by (array-map * ...)
, and array-set!
cannot be applied directly to the broadcast arguments.
But here now if a non-strict array arr1 is broadcast, and computing an element of arr1
has side effects, then computing
(array-all-sum brr1)
may cause those side effects may be executed an undetermined number of times.
Which again may lead to unclear exceptions and behavior that about which it is difficult to reason.
Or should we not worry about such things, say that some uses of such forms are very convenient, and learn not to ask such questions.