In-place scan and un-scan
Description
Adds new API for element-mutable collections that takes a closure that fuses element values and performs a scan (i.e. a progressive reduce) in-place. The other new method performs the inverse operation, taking a closure that removes the contribution one element value plays on another.
Detailed Design
extension MutableCollection {
/// Progressively replaces each element with the combination of its
/// (post-mutation) predecessor and itself, using the given closure to
/// generate the new values.
public mutating func accumulate(via combine: (Element, Element) throws -> Element) rethrows
/// Progressively replaces each element with the disassociation between its
/// (pre-mutation) predecessor and itself, using the given closure to generate
/// the new values.
public mutating func disperse(via sever: (Element, Element) throws -> Element) rethrows
}
Documentation Plan
The methods, types, and the types' properties have block documents. There is also a guide file.
Test Plan
A test file is included.
Source Impact
It adds API.
Checklist
- [x] I've added at least one test that validates that my change is working, if appropriate
- [x] I've followed the code style of the rest of the project
- [x] I've read the Contribution Guidelines
- [x] I've updated the documentation if necessary
As has been discussed in this repo, a “scan” function is going to be named reductions, and there is active work in another PR to design and add that functionality.
In general, if you haven’t already, I recommend taking a look at the existing work and discussions that are ongoing. It’s helpful because you can get a sense of how to build on that work rather than duplicating it.
If there’s new functionality that seems to be missing, it is nice to discuss it with the community under “Issues” before dropping new code into a PR, as there are multiple ways to design any one feature and some will fit better with Swift’s direction than others.
I used "scan" in the title because it's technically a term-of-art, so casuals reading the PR list would have more of an idea what's going on.
The PR with reductions returns a separate object for the results, while the functions here work in-place. This adds a restriction that the seed/first-operand type for the closure must be the same as the element type. I'm not sure the two could share code (without making a distinct result object and copying the results back in, of course).