[swift-evolution] [Review] SE-0032: Add find method to SequenceType

Kevin Ballard kevin at sb.org
Fri Apr 29 19:42:45 CDT 2016


On Fri, Apr 29, 2016, at 05:12 PM, Max Moiseev via swift-evolution wrote:
> HI all,
>
>
> After having discussed this proposal with the members of the standard
> library team, we would like to propose the following updates:
>
> - Since both the language and the standard library have evolved since
>   it was written, the proposal should reflect these changes (things
>   like renaming `Generator` to `Iterator`, adjusting for first
>   argument label rules etc.)
>> (Actually, while writing this, I discovered
>> https://github.com/apple/swift-evolution/pull/276)
> - We believe that renaming `find(_:)` to `first(where:)` would make
>   call sites more clear
>
>> // original proposal
>> numbers.find { isPrime($0) }
>> numbers.find(isPrime)
>>
>> // suggested update
>> numbers.first { isPrime($0) }
>> numbers.first(where: isPrime)
>>
>> In the examples above, when the predicate is passed as a trailing
>> closure, there is no big difference in the invocation, but it changes
>> when we have a named function that we would like to use as a
>> predicate.
>> The Collection protocol already has a property called `first`, that
>> returns an optional element, it also has a method `index(where:)`. In
>> this sense `first(where:)` does not introduce new words to the
>> library vocabulary.
 
first(where:) is a neat idea, but I'm a little concerned about ambiguity
with the property in the presence of type errors. Experimentally, if I
try to call first(where:) with a block with the wrong signature, Swift 3
produces an unhelpful error about how I cannot call value of a non-
function type (i.e. the property) instead of recognizing that I'm trying
to call the function.
 
Example:
 
struct Foo {
var first: Int = 42
 
func first(where: @noescape Int -> Bool) -> Int {
return 42
}
}
 
If I try and call `print(Foo().find(where: { true }))`, you'll note that
the closure has the wrong type signature (it types as `() -> Bool`), and
the compiler gives me the error:
 
<REPL Input>:1:12: error: cannot call value of non-function type 'Int'
Foo().first(where: { true })
~~~~~~~~~~~^
 
Calling it with a block of the correct type works, but having useful
errors is very important.
 
-Kevin Ballard
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160429/dafff5c7/attachment.html>


More information about the swift-evolution mailing list