-
-
Notifications
You must be signed in to change notification settings - Fork 159
[Swift 6]: Update bomb-defuser and clousers #838
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
meatball133
wants to merge
1
commit into
exercism:main
Choose a base branch
from
meatball133:update-closures
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,40 @@ | ||
# About | ||
|
||
[Closures][closures] in Swift are self-contained blocks of code that can be passed parameters to trigger their computation and return values. Closures also capture values from their environment and use them in their computations. As they are self contained, they may be passed around in a program like other values or assigned to constants and variables. | ||
[Closures][closures] in Swift are self-contained blocks of code that can be passed parameters to trigger their computation and return values | ||
Closures also capture values from their environment and use them in their computations. | ||
As they are self contained, they may be passed around in a program like other values or assigned to constants and variables. | ||
|
||
Closures may sound a lot like Swift functions; they do, and for good reason. Functions in swift are just special cases of closures which are required to have a name and are defined using a slightly different syntax. | ||
Closures may sound a lot like Swift functions; they do, and for good reason. | ||
Functions in Swift are just special cases of closures which are required to have a name and are defined using a slightly different syntax. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can "just" be removed? |
||
|
||
While functions in Swift are technically closures, when people refer to "closures" in Swift, they are referring to [closure expressions][closure-expressions]. Closure expressions are written as a parameter list followed by a return type and the keyword `in` followed by the body of the closure, all contained in a pair of curly braces: | ||
While functions in Swift are technically closures, when people refer to "closures" in Swift, they are referring to [closure expressions][closure-expressions]. | ||
Closure expressions are written as a parameter list followed by a return type and the keyword `in` followed by the body of the closure, all contained in a pair of curly braces: | ||
|
||
```swift | ||
{ (a: Double, b: Double) -> Double in | ||
return a + b / 2.0 | ||
return (a + b) / 2.0 | ||
} | ||
``` | ||
|
||
This defines a closure expression of type `(Double, Double) -> Double`, and it can be executed in a similar manner to a function of this type, by applying it to parameters of the appropriate type: | ||
|
||
```swift | ||
{ (a: Double, b: Double) -> Double in | ||
return a + b / 2.0 | ||
return (a + b) / 2.0 | ||
}(10.0, 15.0) | ||
// => 12.5 | ||
// returns 12.5 | ||
``` | ||
|
||
As it's not very convenient to write out the full closure expression every time one wants to execute it, closures can be assigned to names, like any other value in Swift. They can then be called by applying the name to the parameters: | ||
As it's not very convenient to write out the full closure expression every time one wants to execute it, closures can be assigned to names, like any other value in Swift. | ||
They can then be called by applying the name to the parameters: | ||
|
||
```swift | ||
let mean = { (a: Double, b: Double) -> Double in | ||
a + b / 2.0 | ||
(a + b) / 2.0 | ||
} | ||
|
||
mean(13.0, 100.0) | ||
// => 56.5 | ||
// returns 56.5 | ||
``` | ||
|
||
As seen above, closures, like regular functions, may omit the `return` keyword if the body of the closure is a single expression. | ||
|
@@ -38,10 +43,10 @@ Most often, closures are used with higher-order functions, either passed in as p | |
|
||
```swift | ||
[11, 75, 3, 99, 53].contains(where: { (x: Int) -> Bool in x > 100 }) | ||
// => false | ||
// returns false | ||
|
||
["apple", "ball", "carrot"].sorted(by: { (s1: String, s2: String) -> Bool in s1.count < s2.count }) | ||
// => ["ball", "apple", "carrot"] | ||
// returns ["ball", "apple", "carrot"] | ||
|
||
func makeAdder(base: Int) -> (Int) -> Int { | ||
{ (x: Int) -> Int in base + x } | ||
|
@@ -50,7 +55,8 @@ func makeAdder(base: Int) -> (Int) -> Int { | |
|
||
## Inferring closure types | ||
|
||
When the return type or parameter types can be [inferred from context][inferring-closure-types], they can be omitted from the closure expression. Additionally, if the parameter types can be omitted, so can the parentheses around the parameter names: | ||
When the return type or parameter types can be [inferred from context][inferring-closure-types], they can be omitted from the closure expression. | ||
Additionally, if the parameter types can be omitted, so can the parentheses around the parameter names: | ||
|
||
```swift | ||
let mean: (Double, Double) -> Double = { a, b in a + b / 2.0 } | ||
|
@@ -81,6 +87,6 @@ add5(x: 10) | |
- Parameters in closures can not have a default parameter value. | ||
- Parameters in closures may be variadic parameters, but they must have a name and type annotation. | ||
|
||
[closures]: https://docs.swift.org/swift-book/LanguageGuide/Closures.html# | ||
[closure-expressions]: https://docs.swift.org/swift-book/LanguageGuide/Closures.html#ID95 | ||
[inferring-closure-types]: https://docs.swift.org/swift-book/LanguageGuide/Closures.html#ID98 | ||
[closures]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/closures/ | ||
[closure-expressions]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/closures/#Closure-Expressions | ||
[inferring-closure-types]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/closures/#Inferring-Type-From-Context |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,57 @@ | ||
# About | ||
|
||
Closures in Swift are self-contained blocks of code that can be passed parameters to trigger their computation and return values. Closures also capture values from their environment and use them in their computations. As they are self contained, they may be passed around in a program like other values or assigned to constants and variables. | ||
[Closures][closures] in Swift are self-contained blocks of code that can be passed parameters to trigger their computation and return values | ||
Closures also capture values from their environment and use them in their computations. | ||
As they are self contained, they may be passed around in a program like other values or assigned to constants and variables. | ||
|
||
While functions in Swift are technically closures, when people refer to "closures" in Swift, they are referring to closure expressions. Closure expressions are written as a parameter list followed by a return type and the keyword `in` followed by the body of the closure, all contained in a pair of curly braces: | ||
Closures may sound a lot like Swift functions; they do, and for good reason. | ||
Functions in Swift are just special cases of closures which are required to have a name and are defined using a slightly different syntax. | ||
|
||
While functions in Swift are technically closures, when people refer to "closures" in Swift, they are referring to [closure expressions][closure-expressions]. | ||
Closure expressions are written as a parameter list followed by a return type and the keyword `in` followed by the body of the closure, all contained in a pair of curly braces: | ||
|
||
```swift | ||
{ (a: Double, b: Double) -> Double in | ||
return a + b / 2.0 | ||
return (a + b) / 2.0 | ||
} | ||
``` | ||
|
||
This defines a closure expression of type `(Double, Double) -> Double`, and it can be executed in a similar manner to a function of this type, by applying it to parameters of the appropriate type: | ||
|
||
```swift | ||
{ (a: Double, b: Double) -> Double in | ||
return (a + b) / 2.0 | ||
}(10.0, 15.0) | ||
// returns 12.5 | ||
``` | ||
|
||
As it's not very convenient to write out the full closure expression every time one wants to execute it, closures can be assigned to names, like any other value in Swift. | ||
They can then be called by applying the name to the parameters: | ||
|
||
```swift | ||
let mean = { (a: Double, b: Double) -> Double in | ||
(a + b) / 2.0 | ||
} | ||
|
||
mean(13.0, 100.0) | ||
// returns 56.5 | ||
``` | ||
|
||
As seen above, closures, like regular functions, may omit the `return` keyword if the body of the closure is a single expression. | ||
|
||
Most often, closures are used with higher-order functions, either passed in as parameters or returned as results: | ||
|
||
```swift | ||
[11, 75, 3, 99, 53].contains(where: { (x: Int) -> Bool in x > 100 }) | ||
// returns false | ||
|
||
["apple", "ball", "carrot"].sorted(by: { (s1: String, s2: String) -> Bool in s1.count < s2.count }) | ||
// returns ["ball", "apple", "carrot"] | ||
|
||
func makeAdder(base: Int) -> (Int) -> Int { | ||
{ (x: Int) -> Int in base + x } | ||
} | ||
``` | ||
|
||
[closures]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/closures/ | ||
[closure-expressions]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/closures/#Closure-Expressions |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[ | ||
{ | ||
"url": "http://goshdarnclosuresyntax.com", | ||
"description": "Gosh Darn Closure Syntax" | ||
"url": "https://docs.swift.org/swift-book/documentation/the-swift-programming-language/closures/", | ||
"description": "Swift Book: Closures" | ||
} | ||
] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 4 additions & 2 deletions
6
exercises/concept/bomb-defuser/Sources/BombDefuser/BombDefuser.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 20 additions & 17 deletions
37
exercises/concept/bomb-defuser/Tests/BombDefuserTests/BombDefuserTests.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,58 +1,61 @@ | ||
import XCTest | ||
import Testing | ||
import Foundation | ||
|
||
@testable import BombDefuser | ||
|
||
final class BombDefuserTests: XCTestCase { | ||
let runAll = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"]) ?? false | ||
let RUNALL = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"]) ?? false | ||
|
||
@Suite struct BombDefuserTests { | ||
let stringify = { (tuple: (String, String, String)) in "\(tuple)" } | ||
|
||
@Test("flip") | ||
func testFlip() { | ||
let expected = ("Dabba", "Yabba", "Doo") | ||
let got = flip(("Yabba", "Dabba", "Doo")) | ||
XCTAssertEqual( | ||
stringify(expected), stringify(got), | ||
#expect( | ||
stringify(expected) == stringify(got), | ||
"flip((\"Yabba\", \"Dabba\", \"Doo\"): Expected \(expected), got \(got)") | ||
} | ||
|
||
@Test("rotate", .enabled(if: RUNALL)) | ||
func testRotate() throws { | ||
try XCTSkipIf(true && !runAll) // change true to false to run this test | ||
let expected = ("Dooby", "Doo", "Scooby") | ||
let got = rotate(("Scooby", "Dooby", "Doo")) | ||
XCTAssertEqual( | ||
stringify(expected), stringify(got), | ||
#expect( | ||
stringify(expected) == stringify(got), | ||
"rotate((\"Scooby\", \"Dooby\", \"Doo\"): Expected \(expected), got \(got)") | ||
} | ||
|
||
@Test("shuffle", .enabled(if: RUNALL)) | ||
func testShuffle1() throws { | ||
try XCTSkipIf(true && !runAll) // change true to false to run this test | ||
let wires = ("Red", "Yellow", "Black") | ||
let shuffle = makeShuffle(flipper: flip, rotator: rotate) | ||
let expected = ("Yellow", "Black", "Red") | ||
let got = shuffle(113, wires) | ||
XCTAssertEqual( | ||
stringify(expected), stringify(got), | ||
#expect( | ||
stringify(expected) == stringify(got), | ||
"shuffle(113, (\"Red\", \"Yellow\", \"Black\")): Expected \(expected), got \(got)") | ||
} | ||
|
||
@Test("shuffle with other wires", .enabled(if: RUNALL)) | ||
func testShuffle2() throws { | ||
try XCTSkipIf(true && !runAll) // change true to false to run this test | ||
let wires = ("Purple", "Cyan", "Marigold") | ||
let shuffle = makeShuffle(flipper: flip, rotator: rotate) | ||
let expected = ("Marigold", "Cyan", "Purple") | ||
let got = shuffle(253, wires) | ||
XCTAssertEqual( | ||
stringify(expected), stringify(got), | ||
#expect( | ||
stringify(expected) == stringify(got), | ||
"shuffle(253, (\"Purple\", \"Cyan\", \"Marigold\")): Expected \(expected), got \(got)") | ||
} | ||
|
||
@Test("shuffle with another set of wires", .enabled(if: RUNALL)) | ||
func testShuffle3() throws { | ||
try XCTSkipIf(true && !runAll) // change true to false to run this test | ||
let wires = ("Brown", "Orange", "White") | ||
let shuffle = makeShuffle(flipper: flip, rotator: rotate) | ||
let expected = ("Brown", "Orange", "White") | ||
let got = shuffle(0, wires) | ||
XCTAssertEqual( | ||
stringify(expected), stringify(got), | ||
#expect( | ||
stringify(expected) == stringify(got), | ||
"shuffle(0, (\"Brown\", \"Orange\", \"White\")): Expected \(expected), got \(got)") | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They do ... sound like functions? Does that just repeat the first half of the sentence?