Feature Idea: Namespace keyword for grouping related internal entities without resorting to non-initializable structs.


(Jared Sinclair) #1

TL;DR

I’d like to be able to group related internal entities within a namespace declaration, without having to fake it with non-initializable structs:

internal namespace AreaOfConcern {
let SomeString = “SomeString”
let SomeInt = 42
func checkSomething() -> Bool {…}
}

Rationale

Often within a module I find myself wanting to group related internal entities together within a namespace. Free functions and constants are a good example:

internal let SomeString = “SomeString”
internal let SomeInt = 42
internal func checkSomething() -> Bool {…}

So are thematically-related structs:

internal struct CreateANote: Endpoint {
// ...
}
internal struct UpdateANote: Endpoint {
// ...
}
internal struct DeleteANote: Endpoint {
// ...
}

The best way to approximate this currently is to wrap them in a struct, like:

internal struct AreaOfConcern {
static let SomeString = “SomeString”
static let SomeInt = 42
static func checkSomething() -> Bool {…}
}

or for thematically-related structs, to enable tidy usage for the callers:

internal struct NoteEndpoints {
struct Create: Endpoint {
// ...
}
struct Update: Endpoint {
// ...
}
struct Delete: Endpoint {
// ...
}
}

let endpoint = NoteEndpoints.Create(text: String, …)

This solution is somewhat awkward because AreaOfConcern and NoteEndpoints are not really being used as structs so much as an informal namespaces. To communicate this to internal users (and to discourage them from trying to initialize these wrapper structs), you can give them private initializers (which is even more awkward, but helpful):

internal struct AreaOfConcern {
static let SomeString = “SomeString”
static let SomeInt = 42
static func checkSomething() -> Bool {…}

 private init\(\)

}

It would be preferable if there was another keyword, perhaps namespace, that could be used as follows:

internal namespace NoteEndpoints {
struct Create: Endpoint {
// ...
}
struct Update: Endpoint {
// ...
}
struct Delete: Endpoint {
// ...
}
}

The namespace keyword would follow all the same scope and dot-notation rules as a structs, but would not be initializable.

···

--
Jared Sinclair
Sent with Airmail


(TJ Usiyan) #2

+1 from me.

This has apparently become my schtick but the structs are definitely
initializable. Make them enums with no case to guard against initialization.

extension AreaOfConcern {
    init() {}
}
···

On Sat, Feb 20, 2016 at 9:55 AM, Jared Sinclair via swift-evolution < swift-evolution@swift.org> wrote:

*TL;DR*

I’d like to be able to group related internal entities within a namespace
declaration, without having to fake it with non-initializable structs:

internal namespace AreaOfConcern {
  let SomeString = “SomeString”
  let SomeInt = 42
  func checkSomething() -> Bool {…}
}

*Rationale*

Often within a module I find myself wanting to group related *internal*
entities together within a namespace. Free functions and constants are a
good example:

internal let SomeString = “SomeString”
internal let SomeInt = 42
internal func checkSomething() -> Bool {…}

So are thematically-related structs:

internal struct CreateANote: Endpoint {
  // ...
}
internal struct UpdateANote: Endpoint {
  // ...
}
internal struct DeleteANote: Endpoint {
  // ...
}

The best way to approximate this currently is to wrap them in a struct,
like:

internal struct AreaOfConcern {
  static let SomeString = “SomeString”
  static let SomeInt = 42
  static func checkSomething() -> Bool {…}
}

or for thematically-related structs, to enable tidy usage for the callers:

internal struct NoteEndpoints {
  struct Create: Endpoint {
    // ...
  }
  struct Update: Endpoint {
    // ...
  }
  struct Delete: Endpoint {
    // ...
  }
}

let endpoint = NoteEndpoints.Create(text: String, …)

This solution is somewhat awkward because AreaOfConcern and NoteEndpoints are
not really being used as structs so much as an informal namespaces. To
communicate this to internal users (and to discourage them from trying to
initialize these wrapper structs), you can give them private initializers
(which is even more awkward, but helpful):

internal struct AreaOfConcern {
     static let SomeString = “SomeString”
     static let SomeInt = 42
     static func checkSomething() -> Bool {…}

     private init()
}

It would be preferable if there was another keyword, perhaps namespace,
that could be used as follows:

internal namespace NoteEndpoints {
  struct Create: Endpoint {
    // ...
  }
  struct Update: Endpoint {
    // ...
  }
  struct Delete: Endpoint {
    // ...
  }
}

The namespace keyword would follow all the same scope and dot-notation
rules as a structs, but would not be initializable.

--
Jared Sinclair
Sent with Airmail

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution