Linear update, etc. Wolfgang Corcoran-Mathe (08 Oct 2020 15:44 UTC)
Re: Linear update, etc. Adam Nelson (08 Oct 2020 17:27 UTC)
Re: Linear update, etc. Wolfgang Corcoran-Mathe (08 Oct 2020 18:52 UTC)
Re: Linear update, etc. John Cowan (08 Oct 2020 19:13 UTC)
Re: Linear update, etc. Marc Nieper-Wißkirchen (08 Oct 2020 19:28 UTC)
Re: Linear update, etc. Wolfgang Corcoran-Mathe (08 Oct 2020 19:45 UTC)
Re: Linear update, etc. Marc Nieper-Wißkirchen (08 Oct 2020 19:52 UTC)
Re: Linear update, etc. Wolfgang Corcoran-Mathe (08 Oct 2020 19:59 UTC)
Re: Linear update, etc. Marc Nieper-Wißkirchen (08 Oct 2020 20:06 UTC)
Re: Linear update, etc. Wolfgang Corcoran-Mathe (08 Oct 2020 20:29 UTC)
Re: Linear update, etc. Marc Nieper-Wißkirchen (08 Oct 2020 20:37 UTC)
Re: Linear update, etc. Adam Nelson (05 Feb 2021 05:26 UTC)

Re: Linear update, etc. Wolfgang Corcoran-Mathe 08 Oct 2020 18:52 UTC

On 2020-10-08 13:27 -0400, Adam Nelson wrote:
> On 10/8/20 11:44 AM, Wolfgang Corcoran-Mathe wrote:
> > (2) The destructive procedures could be given linear update semantics
> > (see SRFI 1), allowing a wider range of implementations.  Most of the
> > "mutators" already return their flexvector arguments, so it need only
> > be added that these procedures can be implemented non-destructively.
> > The iterators (flexvector-map!, etc.) would take slightly more work.
>
> I'm not sure about this. I made the mutators return the flexvector argument
> so that it is possible to construct a flexvector using a fold, but it
> shouldn't be /necessary/ to use a fold; it is common in other languages to
> use an arraylist-like structure as a mutable accumulator, and append
> elements to it in a for loop, and I'd like to support that pattern as well.

I don't understand this argument.  Why does making the ! procedures
linear update exclude the "mutable accumulator" approach?  For example,
a loop with a mutable accumulator might look like:

    (let ((acc (make-flexvector)))
      (let lp ((i 0))
        (unless (<stop?> i)
          (flexvector-add-back! fv i)
          (lp (+ i 1))))
      acc)

but the changes needed to accomodate a linear-update flexvector-add-back!
are minimal:

    (let lp ((fv (make-flexvector)) (i 0))
      (if (<stop?> i)
          fv
          (lp (flexvector-add-back! fv i) (+ i 1))))

Of course, SRFI 133 doesn't provide linear-update procedures, because
R7RS Scheme vector-*! operations are also explicitly destructive.  When
a series of updates would be made, the explicitly destructive versions
are also easier than rolling one's own state monad with successive
binds.  (The solution there is to have an easy-to-use state monad,
rather than a long list of statements.)

I can certainly see reasons to stick with destructive versions of
these procedures for vector compatibility and for simplifying the
list-of-statements approach.  But *requiring* side-effects here
definitely limits the range of possible implementations.

--
Wolfgang Corcoran-Mathe  <xxxxxx@sigwinch.xyz>

"Fools ignore complexity.  Pragmatists suffer it.  Some can avoid it.
Geniuses remove it." --Alan J. Perlis