PeterPan
PeterPan

Reputation: 744

Swift: A function as an another functions argument

EDIT: I'm aware that I was using the wrong Xcode version for Swift 2, now. Problem solved.

I'm following the Swift 2 book from Apple. At a point there's the following example:

    import Foundation

func hasAnyMatches(list: [Int], condition: Int -> Bool) -> Bool {
    for item in list {
        if condition(item) {
            return true
        }
    }
    return false
}

func lessThanTen(number: Int) -> Bool {
    return number < 10
}

var numbers = [20, 19, 7, 12]
hasAnyMatches(numbers, condition: lessThanTen)

What I think is weird is the last line. Why does it say condition: lessThanTen and not just lessThanTen? My compiler (Xcode) also gives me an error doing it the way it's shown in the book.

Also: why does it only say list: [Int] in the third line but condition: Int -> Bool? Why not something like list: [Int] -> Int?

Upvotes: 0

Views: 376

Answers (3)

MustangXY
MustangXY

Reputation: 358

  1. It says condition: lessThanTen because in Swift you can define "labels", that is, descriptions for the data that a function call requires. It gives you an error because the call would be correct if the function declaration was func hasAnyMatches(list: [Int], #condition: Int -> Bool) -> Bool (at least this would be the case with Swift 1.2). The number sign produces, inside every call to the function, a label identical to the name of the function argument. Said label must not be deleted from the call, since it's there to clarify the purpose of that parameter to whoever invokes the function.
  2. list: [Int] means that the first function argument takes name "list" and is of type [Int]. condition: Int -> Bool means that the second function argument takes name "condition" and is of type "Int to Bool", that is, condition is a function that takes a single argument of type Int and returns a value of type Bool. In fact, if you read the last line, in the call to the function hasAnyMatches the following are passed: i) an array of Ints and ii) a function that takes an Int and returns a Bool (note that when passing functions as parameters we only write their name - no parentheses).

Upvotes: 1

matt
matt

Reputation: 534950

My compiler (Xcode) also gives me an error doing it the way it's shown in the book.

Because the language has changed! In Swift 2, which you are reading about, the function has condition: so your call must have condition:. But you are testing in Swift 1.2, a very different language, where the rules are not the same.

In Swift 1.2, a top-level function declared with condition: means that your call should not have condition:. In Swift 1.2, to require the call to have condition:, the function declaration would have to say # condition:.

You are confusing yourself. Update Xcode so that the language you are using is the same as the language you are reading about.

Upvotes: 2

Duncan C
Duncan C

Reputation: 131408

Swift functions and methods can define their parameters to either have external names or not.

By default, the first parameter omits its external name, and the second and subsequent parameters use their local name as their external name.

Excerpt From: Apple Inc. “The Swift Programming Language (Swift 2 Prerelease).” iBooks. https://itun.es/us/k5SW7.l

The the tag condition: is the external name for the closure that you are passing to your hasAnyMatches function.

That code should compile and run.

Upvotes: 2

Related Questions