Skip to content

[Swift 6]: Update Expert mixolgist and its concept #833

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion concepts/conditionals-switch/.meta/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
"authors": [
"wneumann"
],
"contributors": []
"contributors": [
"meatball133"
]
}
35 changes: 25 additions & 10 deletions concepts/conditionals-switch/about.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# About

A [switch statement][switch] allows you to compare a value against multiple possible matching values.
It allows you to write more concise code than using multiple `else-if` statements.
A switch statement starts with the `switch` keyword followed by the value to be compared.
Then you can define the cases using the `case` keyword followed by the value to be compared against.
The `default` keyword is used to define the default case when none of the cases match.
Like `else-if` statements, `switch` statements only execute the block of code associated with the first matching case.

```swift
switch value {
case 1:
print("One")
case 2:
print("Two")
default:
print("Other")
}
```

Consider the following example:

```swift
if str == "apple" {
print("Let's bake an apple crumble")
Expand All @@ -12,11 +32,7 @@ if str == "apple" {
}
```

While an else-if variant of `if` statements, like the one above, cleans things up considerably compared to a series of `if` statements without `else` clauses, there is still a lot of noise in the code from all of the curly braces. This is where the `switch` statement comes into play. In conditional statements with many possible branches, the switch statement shines. Note, however, that `switch` statements do work a bit differently from `if` statements.

Rather than evaluating a Boolean expression and using the value of that expression to choose the code branch that is run, a simple switch statement takes an input value (or expression which it evaluates to obtain the input value) of some type and compares against one or more values of the same type. If a case is found that matches the input value, the corresponding block of code is run.

Note that all possible cases must be covered in a `switch` statement. In cases like the above where all possible strings _cannot_ be enumerated, a `default` case can be used to match all remaining cases.
This could instead be written as:

```swift
switch str {
Expand All @@ -31,13 +47,10 @@ default:
}
```

Additionally, note that if multiple cases of a switch statement match the input value, only the first matching case is used. An underscore (`_`) can be used to match all values.

Unlike in some other languages, `switch` cases in Swift do not fall through to the next case unless that behavior is explicitly called for with the `fallthrough` keyword. this is the opposite behavior from C which requires explicit `break` statements to prevent fallthrough.

## Binding and where statements

The values being matched in `switch` statements can also be bound to names which can be used in the body of the case. They can also be used in `where` clauses, which are additional boolean expressions that must evaluate as `true` for the case to match.
The values being matched in `switch` statements can also be bound to names which can be used in the body of the case.
They can also be used in `where` clauses, which are additional Boolean expressions that must evaluate as `true` for the case to match.

```swift
let x = 1337
Expand All @@ -48,3 +61,5 @@ default:
print(x, "is not a perfect number")
}
```

[switch]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/controlflow/#Switch
38 changes: 35 additions & 3 deletions concepts/conditionals-switch/introduction.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,38 @@
# Introduction
# About

While the else-if variant of `if` statements cleans things up considerably, there is still a lot of noise in the code from all of the curly braces. This is where the `switch` statement comes into play. In conditional statements with many possible branches, the switch statement shines. Note, however, that `switch` statements do work a bit differently from `if` statements.
A [switch statement][switch] allows you to compare a value against multiple possible matching values.
It allows you to write more concise code than using multiple `else-if` statements.
A switch statement starts with the `switch` keyword followed by the value to be compared.
Then you can define the cases using the `case` keyword followed by the value to be compared against.
The `default` keyword is used to define the default case when none of the cases match.
Like `else-if` statements, `switch` statements only execute the block of code associated with the first matching case.

Rather than evaluating a Boolean expression and using the value of that expression to choose the code branch that is run, a simple switch statement takes an input value (or expression which it evaluates to obtain the input value) of some type and compares against one or more values of the same type. If a case is found that matches the input value, the corresponding block of code is run.
```swift
switch value {
case 1:
print("One")
case 2:
print("Two")
default:
print("Other")
}
```

Consider the following example:

```swift
if str == "apple" {
print("Let's bake an apple crumble")
} else if str == "lemon" {
print("Let's bake a lemon meringue pie!")
} else if str == "peach" {
print("Let's bake a peach pie!")
} else {
print("Let's buy ice cream.")
}
```

This could instead be written as:

```swift
switch str {
Expand All @@ -16,3 +46,5 @@ default:
print("Let's buy ice cream.")
}
```

[switch]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/controlflow/#Switch
7 changes: 6 additions & 1 deletion concepts/conditionals-switch/links.json
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
[]
[
{
"url": "https://docs.swift.org/swift-book/documentation/the-swift-programming-language/controlflow/#Switch",
"description": "Swift Book: Switch"
}
]
3 changes: 2 additions & 1 deletion concepts/control-transfer/.meta/config.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"blurb": "Control transfer allows modifiying the control flow inside loops.",
"authors": [
"wneumann"
"wneumann",
"meatball133"
],
"contributors": []
}
148 changes: 48 additions & 100 deletions concepts/control-transfer/about.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,34 @@
# About
# Introduction

The normal control flow of loops in Swift can be altered using [Swift's control transfer keywords][control-transfer]. One of these keywords, `return` has been seen before in the basics concept exercise. With the use of `return`, if the loop is inside a function, the function will exit at that point, returning whatever value is specified, just as it would at any other point in a function. Two more control transfer keywords that are often used with loops are `continue` and `break`.
Swift has a set of statements that can be used to alter the normal control flow of loops.
These are known as control transfer statements.
You have already seen `return`; this concept will introduce other, which include `continue`, `break`, and labels.
We won't cover `fallthrough` in this concept, but you can read about it in the [Swift book][fallthrough].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is Fallthrough covered? I see it below.


## continue
## Continue

When the `continue` keyword is executed inside a loop, it tells the loop to skip immediately to the next iteration of the loop, skipping any lines of code that may lie between it and the end of the body of the loop. Note that execution resumes with the next evaluation of the Boolean expression for while and repeat-while loops, and not directly to the start of the loop body. So this loop:
Sometimes it is necessary to skip to the next iteration of a loop early, without completing the rest of the statements in the current iteration of the loop.
The `continue` keyword can be used for this.
When `continue` is executed, the loop jumps to the next check to see if the next iteration of the loop can be run, i.e. the `while` in while and repeat-while loops or the check if there's another element in the sequence in for-in loops.

```swift
var count = 1
repeat {
count = 1
while count < 6 {
count += 1
if count == 4 { continue }
print(count)
} while count != 4 && count < 6
```

prints:

```
2
3
```

rather than:
}

```
2
3
5
6
// prints:
// 2
// 3
// 5
```

## break
## Break

When the `break` keyword is executed inside a loop, it tells the loop to jump immediately out of the loop and to resume execution with the first statement following the body of the loop, skipping any lines of code that may lie between it and the end of the body of the loop and not attempting to start another iteration of the loop.
Break is used to exit a loop early.
When `break` is executed, the loop will immediately exit and the program will continue with the first statement after the loop.

```swift
for fruit in ["banana", "grapes", "apple", "strawberry", "kiwi", "lemon"] {
Expand All @@ -46,97 +41,50 @@ for fruit in ["banana", "grapes", "apple", "strawberry", "kiwi", "lemon"] {
// grapes
```

## labels
## Labels

When loops are nested, there are times when one may want to use `break` or `continue` to exit or restart the outer loops that contain the loop in which the `break` or `continue` are used. In cases like these, [labels may be used][labeled-statements] to specify the loop to be exited or restarted. A loop can be labeled by putting a name followed by a colon before the `while`, `repeat`, or `for` that starts the loop.
When loops are nested, there are times when one may want to use `break` or `continue` to exit or restart the outer loops that contain the loop in which the `break` or `continue` are used.
In cases like these, labels may be used to specify the loop to be exited or restarted.
A loop can be labeled by putting a name followed by a colon before the `while`, `repeat`, or `for` that starts the loop.

To see the effect of using labels in this way, consider the following loop.

```swift
for fruit in ["banana", "grapes", "apple", "strawberry", "kiwi", "lemon"] {
outerLoop: for fruit in ["banana", "grapes", "apple", "strawberry", "kiwi", "lemon"] {
print("\n--- \(fruit) ---")
for letter in fruit {
guard letter != "e" else { continue }
if "aiou".contains(letter) {
continue
} else {
print(letter, terminator: "")
}
guard letter != "n" else { break outerLoop }
print(letter)
}
print("\n***")
}
```

This loop takes each word and prints a header containing the full word followed by all of the non-vowel characters as, when the current `letter` is a vowel, the `continue` starts the next iteration of the inner loop with the next character in the word. After all of the non-vowel characters are printed, a line of asterisks and a newline are printed and the next word is processed.

The output of this loop is:

```swift

--- banana ---
bnn
***

--- grapes ---
grps
***

--- apple ---
ppl
***

--- strawberry ---
strwbrry
***

--- kiwi ---
kw
***

--- lemon ---
lmn
***
// prints:
// --- banana ---
// b
// a
```

However, if we label the outer loop, calling it `mainLoop`, and specify continuing _that_ loop when the current `letter` is "e" then any non-vowel letters following the "e" are not printed, nor is the trailing line of asterisks and newline.
## Fallthrough
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Fallthrough
## Fall through

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you mean the keyword, it should be lowercase and not titlecase.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


```swift
mainLoop: for fruit in ["banana", "grapes", "apple", "strawberry", "kiwi", "lemon"] {
print("\n--- \(fruit) ---")
for letter in fruit {
guard letter != "e" else { continue mainLoop }
if "aiou".contains(letter) {
continue
} else {
print(letter, terminator: "")
}
}
}
```

The output of this version of the loop is:
The `fallthrough` keyword is used to fall through to the next case in a switch statement.
This means the the code within the next case will be executed without checking its condition(s).
This will make the switch statement behave like other programming languages where the `break` statement is not required to exit the switch statement after a case is matched.
You can read more about `fallthrough` in the [Swift book][fallthrough].

```swift
let value = 1
switch value {
case 1:
print("One")
fallthrough
case 2:
print("Two")
}

--- banana ---
bnn
***

--- grapes ---
grp
--- apple ---
ppl
--- strawberry ---
strwb
--- kiwi ---
kw
***

--- lemon ---
l
// prints:
// One
// Two
```

Note the difference in the "grapes", "apple", "strawberry", and "lemon" lines.

[control-transfer]: https://docs.swift.org/swift-book/LanguageGuide/ControlFlow.html#ID135
[labeled-statements]: https://docs.swift.org/swift-book/LanguageGuide/ControlFlow.html#ID141
[control-transfer]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/controlflow/#Control-Transfer-Statements
[fallthrough]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/controlflow/#Fallthrough
Loading