array-map [was: last call] Per Bothner (22 Jul 2019 05:13 UTC)
Re: array-map [was: last call] Lassi Kortela (24 Jul 2019 10:37 UTC)
Re: array-map [was: last call] Per Bothner (25 Jul 2019 15:43 UTC)
Re: array-map [was: last call] Lassi Kortela (28 Jul 2019 15:25 UTC)
Re: array-map [was: last call] Per Bothner (04 Aug 2019 23:28 UTC)
Re: array-map [was: last call] Lassi Kortela (07 Aug 2019 18:07 UTC)
Re: array-map [was: last call] John Cowan (24 Jul 2019 11:01 UTC)
Re: array-map [was: last call] Per Bothner (25 Jul 2019 15:35 UTC)
Re: array-map [was: last call] John Cowan (25 Jul 2019 18:49 UTC)

array-map [was: last call] Per Bothner 22 Jul 2019 05:13 UTC

On 7/21/19 12:29 AM, John Cowan wrote:
> I think that SRFI 164 needs an array-map function for element-wise processing, to support what APL calls scalar functions.

I agree array-map is highly desirable.  I decided to leave it out because (1) I was getting essentially no feedback or interest
on this srfi; (2) array-map is not yet implemented in Kawa; and (3) there are issues whether and how to support broadcasting.

>  Here's some proposed language:
>
> Specification:
>
> (array-map proc array1 array2 ...) -> list
>
> Applies proc element-wise to the elements of the array arguments and returns a newly allocated array whose elements are the results of the applications.  The result has the same shape as the array arguments; it is an error if any two arguments have different shapes.  It is also an error if proc cannot accept as many arguments as there are array arguments and return a single value.  The dynamic order in which proc is applied to the elements of the arrays is unspecified.

Reasonable. Broadcasting is an open question.
FWIW, Racket supports it: https://docs.racket-lang.org/math/array_broadcasting.html
The conservative solution is to not support it.  A possible compromise is to allow
a non-array or a rank-0 array argument, but otherwise require all arguments to have
the same shape.

> Rationale:
>
> While it is possible to implement this on top of array-ref, it is considerably more efficient, if the arrays are simple, to implement it directly on top of their backing stores.

The build-array procedure can subsume array-map, and is potentially optimizable.
It would need to be paired with an array-copy procedure to convert the virtual array
to a simple array.  Perhaps a pair of procedures, for mutable or immutable result.
Maybe:
   (array-copy arr) - make a simple mutable copy of arr
   (array-value arr) - make a simple immutable copy of arr

Regardless, I agree array-map is a natural addition.

> When should the result be mutable and when immutable?  Do we need two different map procedures, or is there a natural right answer based on the immutability of the array arguments?  Some plausible answers: (1) always mutable, (2) always immutable, (3) the same mutability as the first argument, (4) mutable unless all the arguments are immutable, (5) immutable unless all the arguments are mutable, or (6) all arguments and the result are required to have the same mutability.

I'd lean towards immutable for simplicity.

> A similar array-for-each procedure, iterating over the elements of the array arguments in lexicographic order and returning an unspecified value, might also be a Good Thing.

Plausible. Or a more general array-fold?

The main issue is how much more effort to put into srfi 164.  Adding more procedures also means adding an
implementation for Kawa. There has been almost zero interest so far, which is highly de-motivating.

It may make sense to finalize 164 as is, specify a range type, and then revisit array-map and
other extensions for an extended srfi.
--
	--Per Bothner
xxxxxx@bothner.com   http://per.bothner.com/