Howdy,

Several months ago, there were a few well-received ideas on the list of adding 
functions which would have static-like dispatch directly scoped to protocols, 
instead of only to types conforming to those protocols.
From a review of the mailing list, it looks like these ideas got lost amongst 
some others, and the goal at the time was “cut & fix”, not “add”.
I’m concerned these may require ABI changes, and I’ve noticed their absence 
negatively affects my code designs, so I’m bring them back up.

The first, and maybe most obvious is protocol-scoped functions.

Right now, static functions require a conforming type, even when default 
implementations exist.

protocol Usable {
        static func use()
}

extension Usable {
        static func use() { }
}

struct User : Usable {
}

User.use()      //compiles
type(of:User()).use()   //compiles

struct AnotherUser : Usable {
        static func use() { }
}

AnotherUser.use()       //compiles & calls  AnotherUser’s implementation 
instead of protocol default

While that is useful, and I’m not suggesting removing it, there is room for 
another kind of static-like method, one which does not require knowledge of an 
instance of a conforming type, nor of a conforming type.  A protocol-scoped 
method

protocol Usable {
}

extension Usable {
        protocol func use() { }
}

Usable.use()    //if accepted, this would compile end execute.

Right now, “static” methods must have a supported type.

Without this feature:
1. many methods become global, which feels very inappropriate in Swift
2. To get nice inits for “Struct clusters”, they become become enums, which 
does not leave them open for extension, the opposite of the intention of 
protocols.

With this feature:
Common pre-validation or -pre-instantiation logic would be available to code 
which works directly with protocols , instead of only code in another module 
which knows about concrete types of it.
The function is not included in the original protocol definition, because it is 
not something which must be implemented by the conforming type.

A derivative concept is protocol-scoped stored vars/lets.  Like static vars & 
let, protocol-scoped vars & lets have static storage, but are name spaced by 
the protocol, instead of getting dumped into the global name space.

As an example, I have a protocol which creates URLRequests for data serialized 
as JSON.  I’d like to have a protocol-scoped “jsonMimeType” var for insertion 
in my algorithm, but that is not currently allowed, at least not using a good 
name-space.  In fact, it’s not even allowed as a static var/let right now, at 
least with a default implementation.  And since this is something that 
shouldn’t be overridden, it doesn’t make sense in a static, who’s default 
implementation could be replaced by a conforming type’s implementation.

Protocol Nested Types.
I understand there’s a lot of work to do to support nested generics, but surely 
nested non-generics are pretty straight forward?

For instance, I have a protocol which requires instances to implement a method 
which returns a case of an enum which is peculiar to that protocol.  I may very 
well wish to make the enum a nested type of the protocol.  This feels like a 
natural extension of the language.

Two of the emails mentioned the desire for “existential protocols”, but in an 
hour of searching, I did not find an “existential protocol manifesto”, so I 
don’t know.

Questions:
1. Have I missed something, and these features are already supported in Swift?
2. Would these features benefit your use of Swift?
3. Would these features affect the ABI?
4. Are these features part of a larger initiative already considered? (links 
please)

-Ben Spratling

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to