github apple/swift-collections 1.4.1
Swift Collections 1.4.1

11 hours ago

This patch release is mostly focusing on evolving the package traits UnstableContainersPreview and UnstableHashedContainers, with the following notable fixes and improvements to the stable parts of the package:

  • Make the package documentation build successfully on the DocC that ships in Swift 6.2.
  • Avoid using floating point arithmetic to size collection storage in the DequeModule and OrderedCollections modules.

Changes to experimental package traits

The new set and dictionary types enabled by the UnstableHashedContainers trait have now resolved several correctness issues in their implementation of insertions. They have also gained some low-hanging performance optimizations. Like before, these types are in "working prototype" phase, and while they have working implementations of basic primitive operations, we haven't done much work validating their performance yet. Feedback from intrepid early adopters would be very welcome.

The UnstableContainersPreview trait has gained several new protocols and algorithm implementations, working towards one possible working model of a coherent, ownership-aware container/iteration model.

  • BidirectionalContainer defines a container that allows iterating over spans backwards, and provides decrement operations on indices -- an analogue of the classic BidirectionalCollection protocol.

  • MutableContainer is the ownership-aware analogue of MutableCollection -- it models a container type that allows its elements to be arbitrarily reordered and mutated/reassigned without changing the shape of the data structure (that is to say, without invalidating any indices).

  • PermutableContainer is an experimental new spinoff of MutableContainer, focusing on reordering items without allowing arbitrary mutations.

  • RangeReplaceableContainer is a partial, ownership-aware analogue of RangeReplaceableCollection, providing a full set of insertion/append/removal/consumption operations, with support for fixed-capacity conforming types.

  • DynamicContainer rounds out the range-replacement operations with initializer and capacity reservation requirements that can only be implemented by dynamically sized containers.

  • We now have working reference implementations of lazy map, reduce and filter operations on borrowing iterators, producers and drains, as well a collect(into:) family of methods to supply "greedy" variants, generating items into a container of the user's choice. Importantly, the algorithms tend to be defined on the iterator types, rather than directly on some sequence/container -- going this way has some interesting benefits (explicitness, no confusion between the various flavors or the existing Sequence algorithms), but they also have notable drawbacks (minor design issues with the borrowing iterator protocol, unknowns on how the pattern would apply to container algorithms, etc.).

    let items: RigidArray<Int> = ...
    let transformed = 
      items.makeBorrowingIterator() // obviously we'd want a better name here, like `borrow()`
      .map { 2 * $0 }
      .collect(into: UniqueArray.self)
    // `transformed` is a UniqueArray instance holding all values in `items`, doubled up 
    let items: RigidArray = ...
    let transformed = 
       items.makeBorrowingIterator()
      .filter { !$0.isMultiple(of: 7) }
      .copy()
      .collect(into: UniqueArray.self)
    // `transformed` holds a copy of all values in `items` that aren't a multiple of 7
    let items: RigidArray = ...
    let transformed = 
       items.consumeAll()
      .filter { !$0.isMultiple(of: 7) }
      .collect(into: UniqueArray.self)
    // `transformed` holds all values that were previously in `items` that aren't a multiple of 7. `items` is now empty.

Like before, these are highly experimental, and they will definitely change in dramatic/radical ways on the way to stabilization. Note that there is no project- or team-wide consensus on any of these constructs. I'm publishing them primarily as a crucial reference point, and to gain a level of shared understanding of the actual problems that need to be resolved, and the consequences of the design path we are on.

What's Changed

  • Add some decorative badges in the README by @lorentey in #591
  • [Dequemodule, OrderedCollections] Avoid using floating point arithmetic by @lorentey in #592
  • Enforce dress code for license headers by @lorentey in #593
  • Bump swiftlang/github-workflows/.github/workflows/soundness.yml from 0.0.7 to 0.0.8 by @dependabot[bot] in #595
  • Documentation updates for latest DocC by @lorentey in #596
  • [BasicContainers] Allow standalone use of the UnstableHashedContainers trait by @lorentey in #597
  • Bump swiftlang/github-workflows/.github/workflows/swift_package_test.yml from 0.0.7 to 0.0.8 by @dependabot[bot] in #594
  • [ContainersPreview] Rename Producer.generateNext() to next() by @lorentey in #599
  • [ContainersPreview] Remove BorrowingSequence.first by @lorentey in #598
  • [CI] Enable Android testing by @marcprux in #558
  • [BasicContainers] Assorted hashed container fixes and improvements by @lorentey in #601
  • Flesh out BorrowingSequence/Container/Producer model a little more by @lorentey in #603
  • More exploration of ownership-aware container/iterator algorithms by @lorentey in #605

New Contributors

Full Changelog: 1.4.0...1.4.1

Don't miss a new swift-collections release

NewReleases is sending notifications on new releases.