This example highlights a problem that it is not possible to know when you are reading the code what's going to happen.
foo(bar(), count: 100)
How many times is bar called? Normally one. but what if parameter is marked with autoclosure? Or it is not marked so in the first version of "foo" API but then changed? Our code still compiles but possibly misbehaves because we are not prepared for "bar" to be called multiple times and we are not alerted of the API change.
Shouldn't we have some explicit marker at the use site to make it obvious that parameter is autoclosed?
This is an old topic. (I've seen another big thread on it but can't find it.)
My issue with this approach is the meaningless 0 and the <. If you're going to disregard the argument, it could be anything. E.g.
stride(from: 0, to: 1000, by: 10)
I don't think polluting Array was or is the way to go. Array was just more of a go-to in the early days. map is fine; it just needs a better iterator to work off of.
Using the exact same API for repeating a value n times for a function that generates a new value n times is a mistake. If you absolutely need to do this, and map isn't cutting it, then use this instead.
extension Array {
public init(
count: Int,
generating value: () throws -> Element
) rethrows {
guard count > 0 else {
self.init()
return
}
try self.init(unsafeUninitializedCapacity: count) {
buffer, initializedCount in
let base = buffer.baseAddress!
while initializedCount < count {
(base + initializedCount)
.initialize(to: try value())
initializedCount += 1
}
}
}
}