> That starts to look an awful lot like a fifth access level just for classes 
> (I know you're not proposing one, but it could start to look that way to a 
> user).

You know, it *could* be.

Suppose that, in `internal` scope, you can do all of these things:

* Subclass a class.
* Add a case to an enum in an extension.[1]
* Add a stored property to a struct in an extension.
* Conform to a protocol (as opposed to just using and constraining with the 
existing conformances).
* Override an individual initializer, property, subscript, or method in an 
extension or subclass.[2]

But `public` does not permit them. You can *use* something that is public, but 
you can't extend it. `open`, on the other hand, *does* allow you to extend 
them. It means that outside code has (about) as much freedom to extend the 
`open` item as code inside your module does.

This approach would allow us to make the "sealing" very tight—if you changed a 
class from `public` to `open`, all of its `public` members would still be 
sealed—without actually making that a heavy burden on programmers who want 
things unsealed.

This also suggests that perhaps `final` is best thought of as foreclosing the 
things that `open` permits, either within a module or in future versions:

* A `final` class can never be subclassed.
* A `final` enum can never have cases added.
* A `final` struct can never have stored properties added.
* A `final` protocol...well, okay, that one's pretty useless. Maybe there just 
aren't `final` protocols.[3]
* A `final` property, subscript, or method can never be overridden.

A `final` thing would be fast both inside and outside the module, because it 
would have guarantees about its size/dynamic type/implementation; an `open` 
thing would be slow both inside and outside, because it would have no such 
guarantees; and a non-`final`, non-`open` thing would be slow externally but 
fast internally.



[1] There's another thread floating around where I've seen people suggest that 
enums could never be open because you couldn't unique integer raw values to 
each case. I think that's a rather narrow view of what an enum is for; many, 
perhaps most, enums don't need raw values, and even those that do could support 
string raw values with little danger.

[2] You can't currently override a member in an extension, but I think that 
would be essential for initializing extension stored properties and especially 
for adding cases to enums (you'd want to override members to handle your 
cases). 

[3] Or maybe a `final` protocol can't be conformed to directly, but only 
through a sub-protocol (which could only be defined within the module). That 
would allow arrangements like "Sequence is the parent protocol of both 
IteratorProtocol and Collection, but all Sequences must conform to one of those 
sub-protocols".

-- 
Brent Royal-Gordon
Architechies

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

Reply via email to