One argument array-for-each, array-every, and array-any?

NumPy basically limits array broadcasting to pointwise operations, or array-map. I think that in a Scheme/Racket library without array comprehensions, one would need to implement broadcasting for arguments to array-fold-left and array-fold-right, too.

The argument processing of SRFI 231's array-for-each, array-every, and array-any is identical to the argument processing of array-map. Because SRFI 231's array-map always returns a generalized (non-strict) array, those "action" procedures can be restricted to have a single array argument without any change in behavior or performance.

I haven't yet committed such a change to my working repository

My question is: I the following too "un-Schemely"?

In Scheme/Racket the routines map, vector-map, every, any, etc. actually apply the procedure to the components of the arguments and return a result, i.e., they are "action" procedures. When array-map in math/array returns a non-strict array, as it does in all circumstances in SRFI 231, array-map just sets up operations to be executed later, relying on later "action" procedures to execute things.

If I change array-for-each, array-any, and array-every to take only a single array argument, that simplifies the implementation, the documentation, etc., with no change in performance or expressiveness, but will programming like the following examples in draft documentation seem too weird?

So basically array-every, array-any, and array-for-each would just evaluate in order the elements of the single array argument, with different rules for when to stop and what to return.

Comments?

I've updated array-for-each, array-every, and array-any to take a single (array) argument, and updated the test file srfi-231/test-mini-arrays.scm at 231-bis · gambiteer/srfi-231 · GitHub I'd be interested to know whether people find this programming pattern (to call these routines with the result of array-map as the sole argument) to be natural.

The five routines that step through all multi-indices in an interval and apply functions to those multi-indices with different kinds of control flow are interval-{for-each|every|any|fold-left|fold-right}.

The first three differ only in when they stop stepping through the multi-indices of an interval (step through all multi-indices; stop when a false value is a result; stop when a true value is a result). Unless we want to allow arrays that can return multiple values I don't see how to do that with array-fold-left and array-fold-right, so I believe those will continue to take multiple array arguments.

Some discussion from the SRFI 231 mail list (Re: Proposal to reduce the number of argument to array-for-each, array-every, and array-any | Simplelists) about the difference between arrays and other "collection" data structures seems relevant here:

Any comments?

Alex Shinn offered an example that would be easier to optimize with multi-argument array-{every|any|for-each} than with single-argument versions: Re: Proposal to reduce the number of argument to array-for-each, array-every, and array-any | Simplelists

That discussion convinced me to keep multi-argument versions of these procedures.

So from here: Improve function names, formatting. · gambiteer/srfi-231@c66fe8a · GitHub the routines array-{for-each|every|any} and interval-fold-{left|right} take multiple array or procedure arguments. array-fold-left and array-for-each have special execution paths for when all array arguments are specialized ("strict") and packed (elements are stored adjacently in memory and in increasing lexicographical order).

Downthread from the email message listed above are various ways to compute dot products of arrays with relative CPU timings. I'd welcome Typed Racket versions of these routines, or ways to express the same thing more idiomatically in math/arrays.

Brad

...
...

So array-map, which always returns a generalized array in this proposal, is unlike the other *-map procedures. It doesn't immediately transform a collection of items into another collection of items. The fact that the procedure "-map" in its name is misleading (as I found out from some correspondence with users of the SRFI 231 sample implementation).

It is a lazy map.

-- hendrik

I believe that having array-{for-each|any|every} take only a single argument may emphasize to users that arrays are different to other collection data structures.

And perhaps we should rename array-map to array-compose to emphasize its true nature.

lazy-array-map ? array-lazy-map ?

A generalized array in SRFI 231 is similar to a nonstrict array in Racket and as math/array's documentation says

I think a data structure is "lazy" if it caches computed results; in math/array there is a procedure array-lazy to return a new nonstrict array that caches its entries as they are computed.