What the code is supposed to do
The function checkForPositive receives an array nums and returns true if at least one number in it is greater than zero, or false otherwise. The program calls it with [-1, 2, 3] and prints Array has positive numbers when the result is true.
The starter code doesn't compile:
func checkForPositive(_ nums: [Int]) -> Bool {
for num in nums {
if num > 0 {
return true
} else {
return false
}
}
}
The compiler reports missing return in global function expected to return 'Bool'.
What goes wrong
There are two problems, and the compiler only reports one of them.
- The function can end without returning. Swift checks every path through a function declared to return
Bool. Ifnumsis empty, the loop body never runs, execution falls off the closing brace, and no value is returned. Swift rejects the code instead of guessing. - The loop decides too early. Both branches of the
ifcontain areturn, so the function always returns during the first pass. For[-1, 2, 3]the first number is -1, it is not positive, and the function answersfalsewithout ever looking at 2 or 3. Adding areturn falseat the end would make the code compile, but it would still print the wrong message.
A single number that is not positive says nothing about the others. Only reaching the end of the array proves that none was positive.
Tracing the starter code
For [-1, 2, 3] the loop starts with num equal to -1. The test -1 > 0 is false, so the else branch runs and the function returns false immediately. The values 2 and 3 are never visited. Even if the compiler let it through, the loop could never run more than one pass, which makes it a loop in name only. A loop that returns on every path of its body is a signal that the logic belongs elsewhere.
The rule to remember is asymmetric. To prove that something exists, one example is enough, so you can return true early. To prove that nothing exists, you must check everything, so false can only come after the loop.
Fixing it step by step
- Remove the
elsebranch. A number that isn't positive should just be skipped, so the loop moves on to the next one. - Keep
return trueinside theif. The first positive number is enough to answer, andreturnends the function at once. - Add
return falseafter the loop. It runs only when the loop finished without finding a positive number, which also covers the empty array and fixes the compiler error.
The fixed code in Swift
func checkForPositive(_ nums: [Int]) -> Bool {
for num in nums {
if num > 0 {
return true
}
}
return false
}
func mainFunction() {
if checkForPositive([-1, 2, 3]) {
print("Array has positive numbers")
} else {
print("Array doesn't have positive numbers")
}
}
With [-1, 2, 3] the loop skips -1, returns true at 2, and the program prints Array has positive numbers.
Swift details worth knowing:
- Missing returns are compile errors. In some languages the same code compiles and returns an arbitrary value. Swift stops you, which is how this bug shows up.
- A
Boolcan be used directly as a condition.if checkForPositive(...)needs no comparison withtrue. - Zero is not positive. The test is
num > 0, so 0 doesn't count.
Why the compiler error is useful
The error message is easy to read as a nuisance, but it points at a real flaw. A function with a return type promises an answer for every input. The empty array is an input like any other, and the original code makes no promise for it. Some languages let that slide and hand back an unpredictable value. Swift makes the gap visible before the program runs, so the question "what should an empty array give?" has to be answered in the code. For this task the answer is false, because an empty array contains no positive number.
Fixing the early return and the missing return together gives a function whose every path is covered: it either finds a positive number and returns true, or finishes the array and returns false.
Two ways to write the same idea
The loop can also be replaced by the standard library: nums.contains { $0 > 0 } returns true when any element passes the test, and false for an empty array. Both versions follow the same rule, and the explicit loop makes the early return and the final fallback visible. Writing the loop by hand once is the best way to see why the final return false has to sit outside it.
Edge cases and common mistakes
- Empty array. Returns
false. - Only the first element decides. This is the bug in the starter code.
[3, -1]would work with it by luck, while[-1, 3]would not. - All non-positive.
[-1, 0]returnsfalse. - Adding
return falseand keeping theelse. The code compiles, and printsArray doesn't have positive numbersfor the example, so the lesson's output is still wrong.
Testing
[-1, 2, 3]givestrue.[-1, 0]givesfalse.[]givesfalse.[0, 5]givestrue.
