> On Mar 14, 2016, at 5:51 PM, Dmitri Gribenko via swift-evolution 
> <[email protected]> wrote:
> 
> Optional.map returns an Optional.
> 
> Array.map returns an Array.
> Set.map returns an Array.
> <any other collection>.map returns an Array.
> 
> I can't say that it is not valid to think about an Optional as a tiny
> collection, but as implemented in Swift, .map() does objectively
> behave differently...
That behavior is, at least partially, because protocols don’t currently support 
this:
protocol CollectionType {
    typealias T
    func map<U>(transform: T->U) -> Self<U> // error: Cannot specialize 
non-generic type 'Self'
}
I *think* I remember reading on here somewhere that the intent is to change map 
and flatMap to return “Self<U>" pretty much as soon as the language supports 
it. Someone from Apple would have to confirm that, though… my memory is quite 
hazy on the matter.

More to the point, in terms of what you could actual do with a variable, 
there’s no real difference between:
var foo: [Int] = []
and
var foo: Int? = nil
In both cases you have to check foo's “count” so to speak, before you can 
safely access its element(s), otherwise the most you can do is pass it along to 
some other code. If the language had the features to support it, Optional could 
literally be defined like this:
typealias Optional<T> = Array<T where self.count <= 1>
While the syntax of how we’d interact with Optionals might change, functionally 
speaking, I can’t think of any difference at all. Both provide storage for a 
variable # of elements (only slightly variable in Optional’s case, but variable 
none the less), both throw equally fatal errors if you try to access elements 
that don’t exist, and provide quick access to those that do exist. Furthermore, 
within the limitation of how many “elements” an Optional can store, it’s 
trivial to convert between the two types:
extension Array {
    init(_ x: Element?) {
        switch x {
        case .None: self = []
        case .Some(let value): self = [value]
        }
    }
}
extension Optional {
    init(arrayLiteral elements: [Optional.Wrapped]) {
        switch elements.count {
        case 0: self = .None
        case _: self = .Some(elements[0])
        }
    }
}

All this suggests, to me anyway, that at least in this regard, they’re the same 
“meta type”. What’s the harm in having the API reflect that?

- Dave Sweeris

P.S. Should we be having this conversation in a different thread? I’m *really* 
bad about going down every rabbit hole I can find, and I don’t want to upset 
the mailing list by dragging them along with me...
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to