> On 18 Feb 2017, at 10:54, Brent Royal-Gordon <br...@architechies.com> wrote:
> 
>> On Feb 18, 2017, at 2:18 AM, Haravikk via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> This is an idea I had while working with collections, and is particularly 
>> inspired by those that use common index types.
>> 
>> Consider for example an array; for indices it simply uses an integer, 
>> however, while this is a perfectly valid type to use it opens up the 
>> possibility of integers from any number of different sources being passed in 
>> by mistake and causing run-time errors. The same is true for wrapping types 
>> that use AnyIndex, or really any type that uses Any* to hide underlying 
>> types, as on the surface all AnyIndex instances give the illusion of being 
>> compatible when they're not, and will only produce errors at run-time when a 
>> conflict arises.
>> 
>> The idea to combat this is simple; a new attribute that can be applied to a 
>> typealias, my working name is @unique, but there's probably a much better 
>> name for it. When applied to a type-alias it indicates to the type-checker 
>> that the type being aliased should be treated as a unique type outside of 
>> the scope in which it is declared.
> 
> I've encountered the same problem in essentially the same place, so I'd like 
> to see a solution too.
> 
> This sounds like a slight variation on what, in previous discussions, has 
> been called `newtype`. IIRC, one of the reasons we've never done `newtype` is 
> that it's not clear which features you want to bring over from the base type, 
> or which types should be used for things like operators. (If you have `func + 
> (lhs: Int, rhs: Int) -> Int`, you don't want `func + (lhs: Index, rhs: Index) 
> -> Index`; you want `func + (lhs: Index, rhs: Int) -> Index`.)
> 
> I'd like to suggest a design that I don't think has been considered before. 
> Currently, if the first type in an enum's inheritance clause is a concrete 
> type, a set of magical behaviors occur:
> 
> * The enum is conformed to `RawRepresentable` with a `RawValue` of the 
> concrete type.
> * Each case is associated with a raw value, specified by a literal attached 
> to the case.
> * `init?(rawValue:)` and `var rawValue { get }` are automatically generated.
> 
> There is currently no equivalent for structs, but I suggest we add one.
> 
> If you say:
> 
>       struct Index: Int {}
> 
> This is automatically equivalent to saying:
> 
>       struct Index: RawRepresentable {
>               var rawValue: Int
>               init(rawValue: Int) { self.rawValue = rawValue }
>       }
> 
> And a special rule is applied: You may not declare any other stored 
> properties.
> 
> Additionally, for both `enum`s and `struct`s with raw types, I would suggest 
> that, if you conform to a protocol which the raw type conforms to and then 
> fail to fulfill its (non-defaulted) requirements, Swift should generate a 
> member which forwards to the raw value's implementation. It might even be 
> nice to do the same when an initializer, method, property, or subscript is 
> declared without providing a body. This would make it easy to decide which 
> functionality should be exposed and how it should be provided--and it would 
> provide a partial way to fulfill the frequent request for syntactic sugar for 
> `Equatable`, `Hashable`, and `Comparable` conformances. (I could imagine this 
> being generalized later on.)
> 
> The main drawback I can see is that the `rawValue` could not be encapsulated, 
> since the conformance to the public `RawRepresentable` protocol could not be 
> made private. That might be acceptable in a convenience feature, or we might 
> decide (perhaps for both `struct`s and `enum`s) that Swift should generate 
> the members without actually conforming the type unless explicitly asked to.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 

Hmm, that's a very interesting alternative; it's a lot like what we have to do 
now ourselves anyway, plus more flexible overall. I still like the idea of 
being able to do something at the typealias itself purely for convenience, but 
that's something that could always come later.

For example:

        typealias Index:Int // shorthand for struct IntIndex: Int {}, typealias 
Index = IntIndex

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

Reply via email to