0

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?

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Unfortunately, it doesn't compile or run. Xcode says the following: Issue: Extraneous argument label 'condition:' in call. Fix-it: Delete "condition:" It works fine if I delete condition:.
@MustangXY gave the hint that there might be a typo (a missing # in the functions declaration). Now it runs without any problems!
It's not a typo. It's because you're using the wrong version of Swift for testing. See my answer...
2

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.

1 Comment

Thanks for that hint! I didn't know that Swift 2 only works with Xcode 7 Beta.
1
  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).

6 Comments

1. Changing the line to func hasAnyMatches(list: [Int], #condition: Int -> Bool) -> Bool removes that error! 'Using' that label is not required but makes the program easier to read, right?
Exactly. Labels are not compulsory but they will make the code more readable and explicit.
Thanks for that explanation! 2. What difference would it make if I write list: [Int] -> Int at the function declaration? Would it make a difference at all? Would it still run?
It wouldn't run anymore because list: [Int] -> Int describes a function parameter of type "array of Ints to int", which stands for a function that takes an array of Ints as its only argument and returns a value of type Int. You would be instead passing it an array of Ints, not a function.
Thank you. Anyway be aware that my explanation is correct for Swift 1.2 (you're most likely using Xcode 6). Swift 2.0 works slightly differently so see @matt 's answer too.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.