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

**URL:** <https://racket.discourse.group/t/one-argument-array-for-each-array-every-and-array-any/4004>\
**Category:** General\
**Tags:** arrays-proposal\
**Created:** [November 13, 2025, 7:53pm UTC](https://racket.discourse.group/t/one-argument-array-for-each-array-every-and-array-any/4004 "2025-11-13T19:53:54Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gambiteer](https://avatars.discourse-cdn.com/v4/letter/g/779978/32.png) [@Gambiteer](https://racket.discourse.group/u/Gambiteer)\
**Post date:** [November 13, 2025, 7:53pm UTC](https://racket.discourse.group/t/one-argument-array-for-each-array-every-and-array-any/4004/1 "2025-11-13T19:53:54Z")

</div>

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

> **[GitHub - gambiteer/srfi-231 at 231-bis](https://github.com/gambiteer/srfi-231/tree/231-bis?tab=readme-ov-file)**
>
> 231-bis

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?

> [@](#):
>
> One can combine `array-map` with "action" procedures like `array-for-each`, `array-any`, and `array-every` to achieve the following:
> 
> ```scheme
> (array-every (array-map = A B)) ;; are all elements of A and B =?
> (array-any (array-map positive? A)) ;; is any element of A positive?
> (array-for-each (array-map write-u8 A)) ;; write a byte array
> 
> ```

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?

---

<div class="post-metadata">

**Author:** ![Gambiteer](https://avatars.discourse-cdn.com/v4/letter/g/779978/32.png) [@Gambiteer](https://racket.discourse.group/u/Gambiteer)\
**Post date:** [November 16, 2025, 11:40pm UTC](https://racket.discourse.group/t/one-argument-array-for-each-array-every-and-array-any/4004/2 "2025-11-16T23:40:59Z")

</div>

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](https://github.com/gambiteer/srfi-231/blob/231-bis/test-mini-arrays.scm) 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.

---

<div class="post-metadata">

**Author:** ![Gambiteer](https://avatars.discourse-cdn.com/v4/letter/g/779978/32.png) [@Gambiteer](https://racket.discourse.group/u/Gambiteer)\
**Post date:** [December 2, 2025, 12:10am UTC](https://racket.discourse.group/t/one-argument-array-for-each-array-every-and-array-any/4004/3 "2025-12-02T00:10:41Z")

</div>

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](https://srfi-email.schemers.org/srfi-231/msg/34733868/)) about the difference between arrays and other "collection" data structures seems relevant here:

> [@](#):
>
> On 11/25/25 04:32, Alex Shinn wrote:
> 
> > On Tue, Nov 11, 2025 at 8:22AM Bradley Lucier \<xxxxxx@purdue.edu  
> > [mailto:xxxxxx@purdue.edu](mailto:xxxxxx@purdue.edu)\> wrote:
> > 
> > ```
> > The old behavior can be obtained with
> > 
> > (array-for-each (apply array-map f array arrays))
> > (array-every (apply array-map predicate array arrays))
> > (array-any (apply array-map predicate array arrays))
> > 
> > So a lot more explicit array-map's in code, with the benefit that it's
> > clear that array-for-each, array-every, array-any just evaluate
> > elements
> > of an array in order, with different control-flow semantics.
> > 
> > ```
> > 
> > I think this is kind of weird from a user perspective. Especially when  
> > used to other collection SRFIs where we generally have:
> > 
> > ```
> > (*-for-each f seq0 seq1 ...)
> > (*-every predicate seq0 seq1 ...)
> > (*-any predicate seq0 seq1 ...)
> > 
> > ```
> 
> Yes, I agree it is "kind of weird".
> 
> I've come to think of generalized arrays ("nonstrict arrays" in Racket's  
> math/array), stateful procedures that carry their domains around with  
> them, as weird enough that they don't count as "collection" data  
> structures like lists, vectors, hash tables, trees, etc.
> 
> The documentation for Neil Toronto's math/array library in Racket states
> 
> > [@](#):
> >
> > To use nonstrict arrays effectively, think of every array as if it were  
> > the array's procedure itself. In other words,
> > 
> > ```
> > An array is just a function with a finite, rectangular domain.
> > 
> > ```
> > 
> > Some arrays are mutable, some are lazy, some are strict, some are  
> > sparse, and most do not even allocate contiguous space to store their  
> > elements. All are functions that can be applied to indexes to retrieve  
> > elements.
> > 
> > The two most common kinds of operations, mapping over and transforming  
> > arrays, are compositions. Mapping f over array arr is nothing more than  
> > composing f with arr's procedure [f on the left]. Transforming arr using  
> > g, a function from new indexes to old indexes, is nothing more than  
> > composing arr's procedure with g [g on the right].
> 
> I've added the interpolated phrases [...].
> 
> 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).
> 
> 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.

Any comments?

---

<div class="post-metadata">

**Author:** ![Gambiteer](https://avatars.discourse-cdn.com/v4/letter/g/779978/32.png) [@Gambiteer](https://racket.discourse.group/u/Gambiteer)\
**Post date:** [December 8, 2025, 7:24pm UTC](https://racket.discourse.group/t/one-argument-array-for-each-array-every-and-array-any/4004/4 "2025-12-08T19:24:41Z")

</div>

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](https://srfi-email.schemers.org/srfi-231/msg/34783841/)

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

So from here: [Improve function names, formatting. · gambiteer/srfi-231@c66fe8a · GitHub](https://github.com/gambiteer/srfi-231/commit/c66fe8ab93f3e89613d320e0403e0722940e3005) 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

---

<div class="post-metadata">

**Author:** ![hendrikboom3](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/hendrikboom3/32/2748_2.png) [@hendrikboom3](https://racket.discourse.group/u/hendrikboom3)\
**Post date:** [December 8, 2025, 8:06pm UTC](https://racket.discourse.group/t/one-argument-array-for-each-array-every-and-array-any/4004/5 "2025-12-08T20:06:19Z")

</div>

...  
...

> 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 ?

---

<div class="post-metadata">

**Author:** ![Gambiteer](https://avatars.discourse-cdn.com/v4/letter/g/779978/32.png) [@Gambiteer](https://racket.discourse.group/u/Gambiteer)\
**Post date:** [December 8, 2025, 9:45pm UTC](https://racket.discourse.group/t/one-argument-array-for-each-array-every-and-array-any/4004/6 "2025-12-08T21:45:08Z")

</div>

> [@hendrikboom3](#):
>
> > 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.

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

> [@](#):
>
> **Nonstrict arrays are not lazy.** Very few nonstrict arrays cache computed elements, but like functions, recompute them every time they are referred to.

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.
