Adding a protocol to an eponymous module

i’ve got a module named HTML that contains a type of the same name, HTML. its tree looks something like:

  • HTML (module)
    • HTML (struct)
    • HTML.Attribute (enum)
    • HTML.ContainerElement (enum)
    • HTML.VoidElement (enum)

so far, so good. it’s not possible to qualify a reference to a declaration in this module because it is eponymous, but that is okay because the HTML type itself is functionally a namespace qualifier.

now i want to add a protocol, let’s call it HTMLOutputStreamable, to this module. but we cannot add a top-level type to the module HTML that is not named HTML, because the module is eponymous, and it will not be possible to use HTML.HTMLOutputStreamable to qualify a reference to this protocol.

how do i get around this?

2 Likes

We need a way saying "public symbols must be qualified explicitly with the module name."

For example:

import (explicit) HTML

struct OS: OutputStream {      // Error
}

struct OS: HTML.OutputStream { // Okay
}

let u = HTML ()      // Error

let u = HTML.HTML () // Okay

Or taking inspiration from C++: :slight_smile:

import HTML

struct OS: HTML::OutputStream {
}

let u = HTML::HTML ()

The only way I found is just use different names, unfortunately.

In that way feels like Swift still misses complete namespacing features. It could be module-level namespacing, but more complete and reliable. I would prefer to have namespaces like in C++ or explicit module definitions as Rust has, but seems like this is not part of the Swift evolution vision.

4 Likes

Would a typealias help, namespacing the protocol under the HTML.HTML type?

extension HTML {
  public typealias OutputStreamable = HTMLOutputStreamable
}
1 Like

unfortunately it will not, because officially HTML.OutputStreamable remains a typealias and not a protocol, and when you query the list of protocols some type T conforms to, you will obtain the original _HTMLOutputStreamable protocol, since a protocol could have multiple typealiases that resolve to it. we do not have a way in the language to say that a typealias should supplant another declaration’s name rather than just be an alias for it.

and since the protocol ought to be underscored, it will not be possible for documentation readers to view anything about it. (i am told this is a problem that currently bedevils the SwiftNIO library, which relies heavily on underscored protocols that host user-facing API.)

well, i experimented with naming the module HyperText, but that just felt way too y2k. on the other hand 2000s aesthetic is certainly coming back in vogue… :slight_smile:

You could always forgo the dot and use Objective-C style “namespacing”.

in this instance, HTML is actually a significant type, it is not a caseless namespace enum.