Lesson 003 – Control Flow

Control FlowIn Lesson 002, we took a look at collections and iterating over those collections. For this lesson, I want to take a look at how you can make decisions in your code. Not every application follows a straight path from beginning to end. There is always some decision to be made. Was the password entered correctly? Is the row odd or even? Is this order being placed after hours? The possibilities are endless.

Introduction
If you have previous programming experience, many of these control flow structures will look familiar to you. Take a look at the following code. What do you think the output will be?

In this case, the program will print out the string “You cannot vote”. A constant named age is declared. We then come to a decision point and it works just like it reads. “If age is greater than or equal to 18, print ‘You can vote’. Else (otherwise), print ‘You cannot vote’.” Fairly straightforward.

This looks almost like a “C Family” if statement, without the parentheses around the if condition. If you remember back to Lesson 002, Swift also omitted the parentheses in our for loops. It is part of the attempt to be a little less “math-y” and easier to read.

Switch Statements

What if you have a very predefined number of conditions to check? In that case, you can use a switch statement. Take a look at this one and guess the output.

Here, the program outputs “Back to the Grind”. With switch statements, you are just falling down the code, looking for something that matches you. For other languages, you need a keyword like break in between your case statements or else the code execution will “fall through” and things could continue to execute. You might want to do this where you might write:

That would accomplish the same thing we did, but I like the Swift way better. When I wrote case “Saturday”, “Sunday”:, I believe that was much more expressive than stacking them up and hoping that someone understands the rules of flow with switch/case/break.

Let…Where

What if I had wanted to make a comparison other than an equality comparison? Could I write code like this?

This makes sense if I read it in English. However, it isn’t valid Swift code. You get an error that says “‘>’ is not a prefix unary operator” and “‘<' is not a prefix unary operator". You just can't lead off with an implication in front of those comparisons. You also cannot do this:

Swift tells you that "expression pattern of type 'Bool' cannot match values of type 'Int'". This kind of comparison is possible, though, and Swift gets around that with the let…where syntax.

You see that we can declare a little constant to be used in each case statement. We let i stand for the input (scoped only to that line) and then we can do the greater than or less than comparison with i in a predicate (the “where i” part) and Swift thinks that is just great. It adds a lot of flexibility to switch statements.

Default Condition

But, there are still some odd problems. Consider this code:

If you’ve been following along, you can run this through the machine and guess the output. We have a constant called guess that is assigned the integer 7. Then we try to find a match in our switch statement. It is not 0, so we go to the next condition. Then, we use our let…where to see if it is greater than zero. Depending on the input, we would lastly check to see if the number is less than zero. In this case, we hit on the greater than zero and would output “Your guess is positive”.

Well, we would if Swift was a little smarter. Instead, this code won’t run with the error “switch must be exhaustive, consider adding a default clause”. Swift insists that when you use a switch statement that you code for every possible inevitability. In this case, I actually have. The number is either less than zero, greater than zero, or zero itself. What else could it be? But Swift’s parser doesn’t do that logic. In this case, I’d have to add a default clause that would literally never be hit. Runnable code would look like this:

I like to be a little bit of a smarty-pants when Swift is annoying me 😉 In this case, our program will now output “Your guess is positive”, just like we expected.

While Loops

Our next kind of control statement is a while loop. It will check the condition is true and then run, then check the condition is true and then run, then check the condition is true and then run…. all until the condition is no longer true. Let’s look at a simple counter.

In this case, it outputs
0
10
20

Repeat…While

What if we wanted it to work first, then check? If counter had initially been 30 or greater, then we never would have printed anything. Luckily, there is code for that™!

In this case, we reverse the syntax a bit and use a repeat…while syntax. This used to be do…while in earlier versions of Swift, but it was changed. Here, we execute and then check, then execute then check, execute, then check… you get it.

For Loops

There is one last control structure I want to look at and that is the for loop. When we looked at collections, we used a for-each loop. In this case, we are just doing a task a certain number of times, not going one by one over a collection.

The standard syntax looks like this and is very similar to what you’d see in many other programming languages.

This prints the numbers 1-10. Just like for-each, the parentheses are gone from c-style and as we noted in Lesson 001, i++ has been deprecated in favor of i += 1. Unfortunately, this entire style of for loop has been marked to go away. If you try to use this, you get a warning that says “C-style for statement is deprecated and will be removed in a future version of Swift”. The replacement is a more “Ruby-like” way to decide how many times to execute.

This code declares a range of numbers, in this case the numbers 1 through 10, inclusive of the number 10. What if I wanted to count to 10 and not use the number 10? In that case, I use ..< instead of and only the numbers 1 through 9 will be output.

Conclusion

Wow, we covered a lot! Feel free to leave a comment if anything was unclear and check out the Lesson 003 playground on the Swift Ninja GitHub repository to have access to the code and play with it yourself to get a better feel for how it works.

Add Comment

Required fields are marked *. Your email address will not be published.