[Pitch] Module selectors

Big fan of this proposal overall, but I do have concerns about the interpretation of :: in qualified lookups, as seen in the Spacecraft.IonThruster::Engine example. This reads to me as searching for the Engine symbol in the Spacecraft.IonThruster package. This isn’t just a matter of associativity, since there is no top-level Engine in the IonThruster package either. So what happens if one is added?

// In module IonThruster
struct Engine { ... }

extension Spacecraft {
     struct Engine {
          // not the same as the top level type
     }
}

// In module NASA
import IonThruster

func makeIonThruster() -> Spacecraft.IonThruster::Engine { ... }
// which Engine does this refer to?

Even if the rule as pitched can successfully disambiguate this situation, it seems potentially very confusing that IonThruster::Engine refers to the top-level type in one context but a nested type in a different context. It also unfortunately prejudices the language against ever supporting native Swift submodules.

I think it would be more consistent to put the module before the whole type: IonThruster::Spacecraft.Engine. The immediate challenge is that IonThruster might export its own top-level Spacecraft type, in addition to extending the one it imported from elsewhere. I believe this can be solved with nesting: IonThruster::(Spacecraft::Spacecraft).Engine would refer to the Engine type nested within the IonThruster module’s extension of the Spacecraft type imported from the Spacecraft module.

14 Likes