I found another old thread (started by @Lily_Ballard) that contains an interesting discussion related to this, after some posts the same random generator example as in this thread is even brought up (by @SusanCheng).
It might be interesting to note that since that discussion, first(where:) has been proposed and implemented, making it trivial to implement first:
public extension Sequence {
/// The first element of the sequence.
/// If the sequence is empty, the value of this property is `nil`.
/// NOTE: Implemented as a function since properties are not expected
/// to be mutating, and renamed from first to sequentiallyFirstElement
/// in order to avoid confusion with the first property of Collection
/// and to make the logic of the operation explicit via its name to
/// reduce confusion in the context of eg a `Set`.
public func sequentiallyFirstElement() -> Element? {
return self.first(where: { _ in true })
}
}
This code example, the name of the function, etc. is not to be taken as a suggestion to add something like this to Sequence, it's purpose is only to highlight some parts of the requirements of Sequence and IteratorProtocol which I find very confusing.
I might be just temporarily extra confused right now, but I'm not even sure why the above method, and eg first(where:), starts(with:), prefix(_: ) and virtually every function on Sequence shouldn't be declared as being mutating ... Can anyone explain why they shouldn't/aren't?