Which (breaking) changes would you be willing to accept in a major language release? [+ Feature wishes]

I would feel better if we force the use of fileprivate over private when it’s actually available in the file’s scope. Cases like private extension reuses private keyword but provides fileprivate semantics instead, introducing unnecessary confusion and styling issues.

I’m personally satisfied with fileprivate (or private(file) as someone proposed), and I believe making the semantics clear at first glance is more important than eliminating keywords.

2 Likes

I agree, especially after re-reading Default Protocol Implementation Inheritance Behaviour - The current situation and what/if anything should be done about it :flushed:

Is it there for anything other that Objective-C compatibly and references? I'd like to see both of those split off.

Yes, this would be fantastic.

Related, I would love to see exhaustivity checking possible for structs. I tend to prefer structs over enums for almost everything, but it would be nice if I could tell the compiler somehow that this is an "exhaustive" struct. Perhaps using CaseIterable or something?

2 Likes

What do you mean by "exhaustive" struct? When using in a switch statement? Please show an example.

public struct ServerEnvironment: Equatable, CaseIterable  {
    public static let allCases = [.production, .qa, .dev]

    public static let production = ServerEnvironment(host: "production.example.com", name: "Production", ...)
    public static let qa = ServerEnvironment(host: "qa.example.com", name: "QA", ...)
    public static let dev = ServerEnvironment(host: "dev.example.com", name: "Development", ...)

    private init( ... ) { }
}

// elsewhere:
let environment: ServerEnvironment = ...
switch environment {
    case .production: // do something only for Production
    case .qa: // do something only for QA
    case .dev: // do something only for Development
}

The "exhaustive" bit is that I would not need a default case because I have handled every possible case as defined by the CaseIterable conformance. It is not possible for the user of ServerEnvironment to get anything except one of those three values.

3 Likes

Maybe this will be possible if we get something like @const and then the compiler could infer that from a @const allCases or something along the lines.

4 Likes

yeah the constexpr proposal(s) have been stuck for months now :pensive:

1 Like

To answer your title: ALL OF THEM.

I put Swift's ability to evolve above everything else.

4 Likes

functions have mangled names, which can be used for hash value for example.

You can currently achieve this in a way like:

public struct ConformanceLimiter {
  fileprivate init() {}
}

public protocol ClosedProtocol {
  var conformanceLimiter: ConformanceLimiter { get } // can not be constructed outside of the library
}

It is a bit ugly, but do the deal.

2 Likes

In this case you can implement the conformanceLimiter as a fatalError:

var conformanceLimiter: ConformanceLimiter {
    fatalError("I'm outside the file so I can't make one, but I can do anything else and conform")
}

Alternatively, you can harvest a ConformanceLimiter from one of the library’s own types and return that.

Yeah, I've done this before with an associated type to prevent "copying" a conformance limiter from one conformer to another:

public protocol MyClosedProtocol {
    static var closer: Closer<Self> { get }

    // regular requirements...
}

public struct Closer<T> {
    // publicly visible, but only internally constructible
    // generic type prevents using a Closer<T> on different conformers of "MyClosedProtocol"
    internal init() { }
}
1 Like