Proposal: Protocols on Steroids
=======================
Change the way protocols and generics work, in particular:
Generic protocol with type parameters inside `<>`, like classes and structs
Allow covariant return types including for generic types
Allow covariant generic argument types with a runtime check that it is of the
correct type
Treat Self as a shorthand for the type name; in particular as though there was
an extra genetic type, `Type<Self: Type>` and everywhere `Self` appeared in the
body the compiler substitutes `Type`
Allow `GenericTypeName.dynamicType` to return the metatype of a generic type
Treat typealias as introducing a generic type parameter that is not part of the
type's type signature (or whatever it is renamed to)
Allow implementations in protocols as well as in extensions to protocols (I
think this is on the cards already)
Allow default stored properties and default inits in protocol, see `Holder`
example below
Disallow overload of a function with a generically typed argument with a
function whose argument is derived from the generic type, must be an override.
Implications
------------
Arrays and a like become covariant (with runtime type check for write) - like
Java arrays but not Java Lists
`Equatable` and co would not be a special type, could have arrays of
`Equatable`s
No need for `AnyXXX` types, the protocol does this directly
No need for `CollectionType` and `Array`, `Array` would become a `protocol` and
a `struct`
Example
--------
A holder of 1 value (chosen to keep the example short - think of it as an
array):
protocol Holder<T> {
default var value: T // See implementation below for what default does
}
In use it could be used like:
var holder = Holder(value: 1) // Holder<Int>
func printout(value: Holder<Any>) {
print("\(value.value)")
}
printout(holder) // Passing a Holder<Int> to a Holder<Any> OK
Implementation
----------------
The above example would be translated by the compiler to something like (though
the names would be changed - names chosen to spell out what is happening):
protocol Holder<T> { // Retains generic type because protocols are types
var value: T { get set }
}
struct DefaultHolder<T>: Holder<T> { // Written because protocol had a
default implementation
var value: T
}
struct HolderInt: DefaultHolder<Int> { // Written because a `Holder<Int>`
was created
var _value: Int
var value: Int {
get {
return _value
}
set {
let temp = newValue as! Int // Runtime type check for write
_value = temp
}
}
Other languages
-----------------
This is how Java arrays work, but not Java generics which are cumbersome to use
in practice but do offer static type checking on write which neither this
proposal or Java arrays offer. Java arrays use a runtime type check.
Dynamic languages and Obj-C normally allow you to store anything in an array
(NSArray). This is different than the behaviour proposed, an array would be
covariant, i.e. a `[Hashable]` could store anything derived from `Hashable` but
could not store an `Equatable` or an `Any` that were not `Hashable`. But the
array could be passed to a function expecting an `[Any]`, for example, and that
function could read from the array._______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution