Left folds Bradley Lucier (17 Sep 2022 22:18 UTC)
Re: Left folds Marc Nieper-Wißkirchen (18 Sep 2022 08:44 UTC)
(missing)
(missing)
Re: Left folds Bradley Lucier (20 Sep 2022 14:15 UTC)
Re: Left folds Marc Nieper-Wißkirchen (20 Sep 2022 14:25 UTC)
Re: Left folds Marc Nieper-Wißkirchen (22 Sep 2022 20:52 UTC)
Re: Left folds Lucier, Bradley J (22 Sep 2022 21:14 UTC)
Re: Left folds Marc Nieper-Wißkirchen (23 Sep 2022 09:25 UTC)
Re: Left folds John Cowan (23 Sep 2022 17:22 UTC)
Re: Left folds Marc Nieper-Wißkirchen (23 Sep 2022 17:30 UTC)
Re: Left folds Bradley Lucier (23 Sep 2022 18:39 UTC)
Re: Left folds Bradley Lucier (24 Sep 2022 00:12 UTC)
Re: Left folds Arthur A. Gleckler (24 Sep 2022 00:24 UTC)
Fwd: Left folds Marc Nieper-Wißkirchen (20 Sep 2022 14:17 UTC)
Re: Left folds John Cowan (18 Sep 2022 10:41 UTC)
Re: Left folds Marc Nieper-Wißkirchen (18 Sep 2022 13:29 UTC)
Re: Left folds Bradley Lucier (20 Sep 2022 00:32 UTC)

Left folds Bradley Lucier 17 Sep 2022 22:18 UTC

The documentation for array-foldl says

Then conceptually |(array-foldl operator identity array . arrays)| returns

|(apply foldl operator identity (array->list (apply array-map list array
arrays)))|

Right now, that's not quite true for generalized arrays.  The
documentation implies that all array elements are evaluated before the
fold is begun, but an expansion of the code for two dimensions is

                      (let ((upper-1 ('#<procedure #17 ##vector-ref>
                                       ('#<procedure #5
##unchecked-structure-ref>
                                        interval
                                        4
                                        '#<type #3 %%interval>
                                        %%interval-upper-bounds)
                                       1))
                             (upper-0 ('#<procedure #17 ##vector-ref>
                                       ('#<procedure #5
##unchecked-structure-ref>
                                        interval
                                        4
                                        '#<type #3 %%interval>
                                        %%interval-upper-bounds)
                                       0))
                             (lower-1 ('#<procedure #17 ##vector-ref>
                                       ('#<procedure #5
##unchecked-structure-ref>
                                        interval
                                        3
                                        '#<type #3 %%interval>
                                        %%interval-lower-bounds)
                                       1))
                             (lower-0 ('#<procedure #17 ##vector-ref>
                                       ('#<procedure #5
##unchecked-structure-ref>
                                        interval
                                        3
                                        '#<type #3 %%interval>
                                        %%interval-lower-bounds)
                                       0)))
                         (letrec ((loop-0 (lambda (f
                                                   operator
                                                   upper-1
                                                   upper-0
                                                   lower-1
                                                   i_0
                                                   result)
                                            (if ('#<procedure #31 ##fx=>
                                                              i_0
upper-0)
                                                result
                                                (letrec ((loop-1 (lambda (f
operator
upper-1
upper-0
lower-1
i_0
i_1
result)
                                                                   (if
('#<procedure #31 ##fx=> i_1 upper-1)
(loop-0 f
operator
upper-1
upper-0
lower-1
('#<procedure #39 ##fx+> i_0 1)
result)
(loop-1 f
operator
upper-1
upper-0
lower-1
i_0
('#<procedure #39 ##fx+> i_1 1)
(operator result (f i_0 i_1)))))))  ;; <<<<<<< HERE
                                                  (loop-1 f
operator
                                                          upper-1
                                                          upper-0
                                                          lower-1
                                                          i_0
                                                          lower-1
result))))))
                           (loop-0 f
                                   operator
                                   upper-1
                                   upper-0
                                   lower-1
                                   lower-0
                                   identity)))

So we intersperse evaluations of the "combining" operator (named
operator) with evaluation of the array-getter (here named f) at the
place marked HERE.  With call/cc and some set!'s one could probably
detect the difference.

If the user wants to play call/cc games with operator, then I don't see
how we can stop her, or why we would want to, but should we evaluate
array-getter at all multi-indices before starting to combine things with
operator, as the documentation implies?

The code for array-foldr does evaluate array-getter at all multi-indices
before combining results with operator:

                       (let ((upper-1 ('#<procedure #17 ##vector-ref>
('#<procedure #5 ##unchecked-structure-ref>
interval
4
'#<type #3 %%interval>
%%interval-upper-bounds)
                                                    1))
                             (upper-0 ('#<procedure #17 ##vector-ref>
('#<procedure #5 ##unchecked-structure-ref>
interval
4
'#<type #3 %%interval>
%%interval-upper-bounds)
                                                    0))
                             (lower-1 ('#<procedure #17 ##vector-ref>
('#<procedure #5 ##unchecked-structure-ref>
interval
3
'#<type #3 %%interval>
%%interval-lower-bounds)
                                                    1))
                             (lower-0 ('#<procedure #17 ##vector-ref>
('#<procedure #5 ##unchecked-structure-ref>
interval
3
'#<type #3 %%interval>
%%interval-lower-bounds)
                                                    0)))
                         (letrec ((loop-0 (lambda (f
                                                   operator
                                                   identity
                                                   upper-1
                                                   upper-0
                                                   lower-1
                                                   i_0)
                                            (if ('#<procedure #31 ##fx=>
                                                              i_0
upper-0)
                                                identity
                                                (letrec ((loop-1 (lambda (f
operator
identity
upper-1
upper-0
lower-1
i_0
i_1)
                                                                   (if
('#<procedure #31 ##fx=> i_1 upper-1)
(loop-0 f
operator
identity
upper-1
upper-0
lower-1
('#<procedure #39 ##fx+> i_0 1))
(let ((item (f i_0 i_1)))
(let ((result (loop-1 f
operator
identity
upper-1
upper-0
lower-1
i_0
('#<procedure #39 ##fx+>
i_1
1))))
(operator item result)))))))
                                                  (loop-1 f
operator
identity
                                                          upper-1
                                                          upper-0
                                                          lower-1
                                                          i_0
lower-1))))))
                           (loop-0 f
                                   operator
                                   identity
                                   upper-1
                                   upper-0
                                   lower-1
                                   lower-0)))

But you can see that with lambda-lifting, 9 words (8 arguments plus the
return label) are pushed to the stack for each array item iteration.

Brad