Why can't Protocols be nested in other Types?

We can nest classes, structs & enums:

class TestClass {
     class OtherClass {}
     struct OtherStruct {}
     enum OtherEnum {}
}


Why can't we also nest protocols?

class TestClass {
     protocol Delegate {}  // error: Declaration is only valid at file scope
}


So far the workaround is to declare it at file scope using and use a typealias instead.

The underscore prefix makes it clear that the global symbol name is not intended for direct use.

class TestClass {
     typealias Delegate = _TestDelegate
}

protocol _TestDelegate {}


Is this just not yet implemented or is there a reason for not supporting that at all?

I'm confused as to why that would be beneficial in the case you outline. The only reason to define a delegate protocol is to allow classes outside the enclosing class's context to implement it.

I think he is interested in namespacing. He wants the type of the delegate protocol to be 'TestClass.Delegate'. Makes sense to me...

Exactly. I'd like to reduce the global namespace pollution and it makes the connection between some types and their related protocols much clearer.

Best example is all the XYZDelegate protocols.

Why are you not using the Swift ways to do that? Private access and frameworks.

One of the main use cases for nesting is to bundle abstractions that belong together. Doing this via frameworks does not scale since frameworks only represent larger software components. Here's an example for two classes each providing their own factory type:


class Foo {
  protocol Factory {
    func newFoo() -> Foo
  }
  ...
}
class Bar {
  protocol Factory {
    func newBar() -> Bar
  }
  ...
}


In Swift, a programmer needs to workaround this by using naming conventions, e.g. `FooFactory` and `BarFactory`.

Frameworks are far too heavy-weight to be practical within a given codebase.


There are plenty of cases where one wants to encapsulate a small bit of collective functionality across multiple types (and multiple files) that absolutely do not warrant a framework. This problem would be easily solved if Swift provided for lighter-weight "namespaces" or "sub-modules" that could be described declaratively. Something like:


namespace Foo

class Foo.Bar { ...

struct Foo.Bast { ...

protocol Foo.Blah { ...


I filed a radar about this back with 1.0 was released, and it was immediately marked as a duplicate, so I have some hope that there might be an answer at some point.


IMHO, it would be even better if 'internal' applied to such a namespace, but I know that's a losing battle. As it stands, in general Swift, I only have one access level (private) to model encapsulation with, because I don't typically build frameworks.

That's a thing I don't get - What is heavy at frameworks? They are easily created and have nearly zero overhead.

You lose optimization opportunities for example. Its like put all the optimizations made with "whole module optimization" in the trash just to organize the code.

Well time to be less theoretical: WHAT should be organized and protected from WHAT? I still believe any sensible design is doable with frameworks and/or private access restrictions. For example helper elements should never leave their source file: in a list file only the list class should be non private, node class etc stay private.

I mean, compiler optimization, for performance reasons. Some sample presented on WWDC increase about ~20 fps only making "in module" optimizations. The compiler should see all code to make the correct assumption with memory management, inline access, etc...

Frameworks just split the code optimization opportunities. Doesn't matter what are you protecting, using Frameworks, you code will be larger and less performatic. So, i dont think is a good idea split the code in a Framework just to get a new namespace.

I see - It's a case of premature optimization … That's the reason for me wanting a direct example what should be seperated from what by namespacing. If the code is so strongly entwined it shouldn't be seperated of course.

Yes, I've been wanting this for the same reason: Namespacing and DRY.


This:

class SomeClass {
  protocol Delegate {
    func someClassDidThis()
  }
  
  var delegate: Delegate

  init(delegate: Delegate) {
    self.delegate = delegate
  }
}


Vs:

class SomeClass {
  var delegate: SomeClassDelegate
  init(delegate: SomeClassDelegate) {
    self.delegate = delegate
  }
}
protocol SomeClassDelegate {
 func someClassDidThis()
}

You're right, probably this kind of code will be never be splitted in two namespaces anyway. But this is just a example, frameworks are not "zero cost", and Swift sometimes (for now) can be very slow without these optimizations, and will never replace tons of c++ codebase for several projects.


But my point is very simple: My only option to create a "subscope" is making a framework? Ok, its easy to create, and easy to maintain, but i really need the "entire" framework infrastructure to avoid XYZDelegate? Doesn't look a big problem, but i think its a good idia make nested protocols like we do for nested types.

Why not simply like that?


protocol Factory {
  typealias bla
  func new() -> bla
}

I'm not sure how this helps bundling abstractions that belong together. You are solving a completely different problem here. Just think of one factory needing two `Int` values as parameters of the constructor, and the other a `String` value.


class Foo {
  protocol Factory {
    func newFoo(x: Int, _ y: Int) -> Foo
  }
  ...
}
class Bar {
  protocol Factory {
    func newBar(string: String) -> Bar
  }
  ...
}
Why can't Protocols be nested in other Types?
 
 
Q