Cross-Import Overlays

you're not sure if you should put the extensions in module A or module B

It is not just about extensions. If a class from one module depends on a protocol from another module, and you want to provide a conformance, then:

  1. You write a retroactive conformance: People really shouldn't be writing these. Retroactive Conformances vs. Swift-in-the-OS
  2. One of the package depends on the other: This introduces build ordering issues as the compilation must proceed one after the other instead of in parallel. Moreover, in the case these are not system frameworks, people who only want one package need to compile more things which they are not using.

But making a whole new module C, which is a new kind of module which is implicitly imported if both A and B are, just seems like overkill.

These are a generalization of the overlays that we already have today. Moreover, you can use them like any other module with an explicit import _NumericKitFormatKitAdditions in the source if you wish to do so.

People who import A and B will see the extensions anyway - so, I mean... does it really matter?

I don't follow. Are you proposing that the solution one should pick in the above example is that NumericKit should depend on FormatKit (or vice-versa)?

What we do now is very easy to reason about, and gives you access to implementation details of A or B (depending which framework you decide to put them in).
This change would be harder to reason about and end up with access to neither A nor B's implementation details.

If you need access to the implementation details, you can still put that code in the corresponding module where the implementation resides. This change is additive, it does not take away that freedom.


And for what?

@phoneyDev also echoed a similar sentiment.

I don't see the problem that's being solved.

Let me reiterate the key benefits of this approach:

  1. Build ordering: Using cross-import overlays provides greater build parallelism (and potentially less compilation work) compared to having package depend on the other. This is particularly beneficial if you are building from source.
  2. No worries about retroactive conformances (and generally cross-cutting functionality): The cross-import overlay provides a natural home for this functionality.
  3. Good defaults + opt-in explicitness: You get the functionality of both frameworks if and only if you import both of them [same as today] but without additional clutter. On the other hand, if you want your code to explicitly list each and every import, you can do that too.
1 Like