I don't think so; it's more about the fact that Array<S: Sequence>.init(_ s: S)
now silently accepts any Optional<S> where S: Sequence
. The name map
is already duplicated today, yet Optional.map
still returns an Optional, which doesn't fit into a non-optional Sequence parameter (you'd have to unwrap it first). If Optional started conforming to Sequence, in cases like this it'd become easier to forget you have an Optional.

you can only conditionally conform to a protocol once, so someone who might want to use Optional : Sequence where Wrapped == MyType in their own project, with an implementation that makes sense to them, will be barred from doing so if this ships
That last point is key here. As a result, IMO, only the most “obvious” conditional conformances–basically, those that allow replacing existing types (such as CountableRange being replaced with Range where Bound : SignedInteger), or are already partially simulated (such as Array : Equatable where Element : Equatable) should be shipped as conditional conformances that everyone has to abide by.
Isn’t this one of those “obvious” conditional conformances, though?
I am hard-pressed to think of any reasonable interpretation in any context of Optional<SequenceType>.none
as a Sequence
in which it should be something other than the empty sequence. At least not any example that isn’t hideously contrived. (I’m certainly open to a compelling example if you have one.)
This feels very much like Arrays being equatable when their elements are; there’s only one sensible meaning for that to have.
Not at all. The usual interpretation of optional types as a collection I am familiar with is as a collection of zero or one elements whose element type is Wrapped. The proposed interpretation seems strange to me as it artificially equates an empty sequence with .none.

The usual interpretation of optional types as a collection I am familiar with is as a collection of zero or one elements whose element type is Wrapped.
This interpretation may be usual in ML-family languages, but I'm not convinced it makes useful sense. It feels more like a clever functional hack than something that meets expectations or aids understanding. I can view Int
as a collection of empty tuples, but that doesn't mean it’s useful to do so.
Can you think of a practical situation where, given thing: [Thing]?
, a reasonable person would expect for x in things
to loop once, instead of looping over each thing? Because I’ve certainly wanted the latter plenty of times.
The only use I can imagine for treating it as a collection of 0/1 elements, is to share the same interface for features like map
, flatMap
, forEach
(which would be better off as something like ifSome(then:)
), isEmpty
, etc.
But those things can exist without a formal conformance to Collection
, and more importantly, it leads to some really dumb available API:
let x: Int? = 5
// If optional was a colleciton of 0 or 1 elements:
x.first
x.last
x.removeFirst()
x.removeLast() // two names for something that'll always be the same ... interesting
x[12] // wut
x.index(after: x.startIndex) // ???
x.count // why would anyone want this?

I am hard-pressed to think of any reasonable interpretation in any context of Optional<SequenceType>.none as a Sequence in which it should be something other than the empty sequence. At least not any example that isn’t hideously contrived. (I’m certainly open to a compelling example if you have one.)
On the contrary, I think that's a rather unreasonable interpretation:
Recall that, in Swift, an array of arrays (or any sequence of sequences) is not automatically flattened for iteration. In other words, iterating over [[[T]]]
doesn't give you elements of type T
but of type [[T]]
.
This proposal would flatten (iteratively) iteration for a type [T]???
but not for a type [[[T]]]?
in the same breath as claiming that Optional<S : Sequence>
is a Sequence
. That is, not only would it cause Optional
not to behave like other Sequences
, it would do so ironically in the conformance of Optional
to Sequence
.
Recall also that, in Swift, let z: T?? = nil
is not equivalent to let a: T?? = .some(nil)
, and that this is a deliberate design decision.
Now, if let x: [T]? = nil
is an empty Sequence
, then what is let y: [T]? = []
in terms of what elements you'd get on iteration? Based on the principle above, y
(an Optional
value wrapping an empty Sequence
) should be a different sequence from x
: in other words, a non-empty sequence. If not empty, then the only alternative would be to conclude that y
ought to consist of one element of type T?
that is nil
. Maybe not too bad. But the conformance Optional : Sequence where Wrapped : Sequence
applies recursively. Therefore, if y
has one element, then let w: [T]??? = []
must consist of three elements of type T???
: .some(.some(nil))
, .some(.some(nil))
, .some(.some(nil))
.
This proposal doesn't do that at all because it would be quite insane, and instead w
, x
, and y
would all have equivalent sequences. However, this goes against a fundamental expectation of Optional
(that U??
is not the same as U?
).
No, this is not an "obvious" conformance; in fact, I believe it would be entirely inconsistent with existing Sequence
and Optional
behavior in Swift for the reasons above.

The only use I can imagine for treating it as a collection of 0/1 elements, is to share the same interface for features like map, flatMap, forEach (which would be better off as something like ifSome(then:)), isEmpty, etc.
But those things can exist without a formal conformance to Collection, and more importantly, it leads to some really dumb available API:
Yes, map
and flatMap
can and do exist without a formal conformance to Collection
. Nor do I think Optional
should conform to Collection
.
But if Optional
would conform to Sequence
, it certainly ought not to conform in another way that's incompatible with treating it as a collection of 0/1 elements [at least, not vended by the standard library]. Not least because there would then be two incompatible methods named map
(and the same for flatMap
, etc.). But also because it is not merely a silly compiler limit that Optional
should not conform to Sequence
in two different ways: it's also not good design for Optional
to have semantics that conform to Sequence
in two different ways--even if one such conformance is unstated outright.

let x: Int? = 5 // If optional was a colleciton of 0 or 1 elements: x.first x.last x.removeFirst() x.removeLast() // two names for something that'll always be the same ... interesting x[12] // wut x.index(after: x.startIndex) // ??? x.count // why would anyone want this?
This is not "really dumb." It's not particularly useful for the concrete type, but the point is that it may enable useful generics. For the same reason, we already have a CollectionOfOne<T>
type that conforms to Collection
. In some ways, Optional : Collection
would result in essentially a mutable version of CollectionOfOne<T>
.
There's nothing wrong with x.first == x.last
, as shown by CollectionOfOne
. In the case of Optional
, x.first == x && x.last == x
, which is actually a rather elegant result. Of course, x.removeFirst()
does the same thing as x.removeLast()
, as you would expect for a "mutable CollectionOfOne
." No one would attempt to write x[12]
, obviously. x.index(after: x.startIndex) == x.endIndex
, as expected. And x.count
would provide you with another way of telling if your Optional
is nil
; you won't need it for concrete work, but it's not like you can write == nil
if you're working with a generic Collection
.
@Paul_Cantrell I don't have anything to add to the excellent answer @xwu has provided.
Just +1
his post, then
Your point about the inconsistency of what would be flattened and what isn't is a good one. I concede.
But I disagree with your points about Optional as a collection. "No one would attempt to write x[12]" Sure, but the compiler lets them. You shouldn't crowbar Optional into Collection, even if you can make it work. first
, last
, count
, etc. could all be made to work, but it's so far removed from what an Optional represents. Adding indices into the picture only makes it worse.

This interpretation may be usual in ML-family languages, but I’m not convinced it makes useful sense. It feels more like a clever functional hack than something that meets expectations or aids understanding. I can view Int as a collection of empty tuples, but that doesn’t mean it’s useful to do so.

But I disagree with your points about Optional as a collection. “No one would attempt to write x[12]” Sure, but the compiler lets them. You shouldn’t crowbar Optional into Collection, even if you can make it work.
We don't disagree here. I don't think Optional
should conform to Collection
. As pointed out in another thread, promotion from T
to T?
would make that feature downright dangerous. My point was that, semantically, Optional
can be regarded as a Collection
type with either zero or one element. That's all.
Unsurprisingly, Xiaodi absolutely nailed it. I think the desired goal would be better achieved with (say) a for?
keyword that iterates over a non-nil sequence and does nothing for a nil sequence. Given that for __ in __
is already syntax built to handle a Sequence
, it feels like the correct approach to handle a Sequence?
is parallel syntax such as for? __ in __
. The same idea could be applied throughout the language; switch?
for an optional enum, while?
for an optional Bool, etc. Handling this issue at the language level seems better than handling it at the protocol level.
I think Optional should be array like, with either 0 or 1 element. It is useful in scientific programming were you often write func sin<S>(xs: S) -> [Double] where S: Sequence, S.Element == Double { var result: [Double]; for x in xs { result.append(sin(x)) }; return result }
.
Uh, no. That's what Array.map
is for. And you forgot to reserveCapacity
(yet another reason to use map
)
xs.map(sin)
?
Strong -1. Implementing this for Sequence
means that we'd have to implement it for every other protocol on the standard library, for this sort of a thing to make intuitive sense. It isn't scalable, and it's inconsistent with how Optional
implements certain protocols (Encodable
, for example. Would you encode an empty value, as it does now, or throw an error if the Optional
is nil
?).
Yes better implementation. The main point is that you want optional to be a Sequence of 0 or 1 element so that you can use your