There should be a way to reference the current module

A number of times now I have run into a situation where it would be really nice too have a general way to reference the current module.

For instance, this will often come up in cases where it's desirable to have an inner type with the same name as a top-level type. So for instance, imagine we're inside a module called MyGreatModule and we have the following code:

protocol Foo { ... }

struct Bar {
    struct Foo: MyGreatModule.Foo { ... }
}

Here it's possible to have both the protocol and the inner struct named Foo, but we need to explicitly reference the protocol relative to the module name to avoid ambiguity.

This creates some friction with respect to how easy it is to refactor this code:

  • If I rename the module, this code no longer works

  • If I copy and paste this code into another module, it no longer works

Also using the module name here feels a bit hacky, since it's not declared anywhere within the code itself, and it's essentially just an argument passed to the swift compiler, so your code is no longer self-contained and now has an external dependency on the build system if you do this.

So it would be really nice to have a general way to reference the enclosing module which is independent of the individual module name.

For instance, something like:

protocol Foo { ... }

struct Bar {
    struct Foo: Module.Foo { ... }
}

Where Modlue behaves like the Self keyword used within a type.

8 Likes

I‘m against the name Module as it‘s such a generic name and has other use cases, it would be a shame to burn it. Honestly using the actual module name is fine for me. I personally haven‘t seen many cases where I needed that to resolve ambiguity. I‘m not opposed to the general idea though.

I‘m not at my mac, can we actually create a typealias for the module name? Can someone test it.

Arguably, this is a feature, not a bug.

In any case, if we ever adopt the Module::Type syntax (see previous discussions), then what you're talking about would naturally fall out as ::Type.

2 Likes

But would you agree that it is an issue that renaming a module should break code within that module?

This seems like a fairly elegant solution. What is the motivation for using the :: operator for denoting a module rather than the dot which is currently used?

Yes this is just a strawman name, and I agree that it probably makes sense to use a more specific name which has less obvious applications across code in general.

1 Like

A syntax is being developed to disambiguate modules from types of the same name and allow the use of methods of identical name extending the same type vended by different modules. (This is not my idea; see, as I alluded to, other threads in this forum.)

2 Likes

A situation I'm running into is a codebase where some of the files are used for multiple targets. Both targets have some common definitions, but depending on the target they belong to a different module.

For this a general name for accessing the current module would come in really handy.

I'm now working around the issue by using preprocessor macros;

#if os(tvOS)
typealias Configuration = AppTV.Configuration
#else
typealias Configuration = App.Configuration
#endif

This is not an answer to the general problem, but it's possible for a module name to be different from the target name—check the Xcode build settings. (The package manager doesn't have a setting for this, but the package manager encourages putting common files into libraries much more than Xcode does.)

2 Likes

Interesting, I'll try that tomorrow