I'm starting to take a look at using Collections, and I quickly noticed that because the benchmark executable is part of the base SwiftCollections package that also means SwiftPM is resolving compatible versions of SwiftArgumentParser and SwiftSystem - which can cause long-term headaches someone also uses those libraries in their project and want to upgrade (or needs to pin to older versions).
Should this be split into a separate package & repo to avoid causing dependency problems?
They are not dependencies of any real product, and will go away automatically when the fullness of SE‐0226 is finally activated. I was actually glad to see swift-collections structured this way, as it increases the likelihood Apple itself will start feeling the friction of the advanced resolution still being disabled.
If the headaches it causes really are too much to wait until the real problem is solved, then I recommend hiding the benchmarks behind an environment variable like the SwiftPM package does here. To me that seems better than splitting the package in two to dodge a temporary problem.
Edit: Actually, just removing the product declaration would probably erase the problem immediately. The executable would still be available when swift-collections is the top‐level package, but no client would know of the executable’s existence.
I feel quite strongly that putting the benchmarks in a different repository than the collection implementations would be an unreasonable obstacle to contributions -- people would need to change multiple packages in different repos and then figure out how to put them in edit mode, keep track of & review multiple PRs etc.
So I intentionally put the data structures, their tests and their benchmarks in the same repository, knowing full well that this is likely to cause technical problems down the road. These problems must be resolved, but this needs to happen without forcing library authors to splinter their code into a myriad tiny repositories. I don't believe a build system should have the mandate to dictate such major decisions on development organization.
That said, Swift Collections explicitly doesn't provide any source compatibility guarantees for its tests or benchmarks, so we did leave the door open to change their configuration in whatever way necessary.
(I expect the tests will eventually be affected too -- the test infrastructure really really wants to be a separate project.)
One potential workaround I considered was to move the benchmarks (and the tests!) to a hidden package under a subdirectory of the swift-collections repository. Unfortunately, swiftpm dislikes such setups, so I was forced to put everything in the top level package.
A nuclear option would be to use separate package manifests in production vs development, with the production version missing target configurations for tests and benchmarks. (This would make development / CI a little more difficult, but not as much as separate repositories, and it would unblock production use.)
I expect the collection implementations are going to stabilize much, much sooner than the benchmarking facility or the test infrastructure. Superficially, it'll be weird for a stable package to depend on an unstable one, but the world is a strange place.
The dependency graph between these packages is going to get really interesting, and fast -- it is already very painful that the benchmarking project isn't able to import Swift Collections.
Apple is a company so I don't think it can feel anything, but it's made of people with feelings. I promise this particular employee is very acutely aware of some SwiftPM-related friction, and I'm greatly looking forward to this and other pain points getting resolved.
Oh interesting, I did not know that! This sounds like this would be a good idea to implement.
This still wouldn't allow swift-collections-benchmark to import swift-collections, but if it resolves dependency hell in production apps, then that's still a win!