Skip to content

Auronas: remove force casts on dequeuing #969

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

Closed
wants to merge 2 commits into from
Closed
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
5 changes: 1 addition & 4 deletions A-Star/AStar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,7 @@ public final class AStar<G: Graph> {
/// - Precondition: both `source` and `target` belong to `graph`.
public func path(start: G.Vertex, target: G.Vertex) -> [G.Vertex] {
open.insert(Node<G.Vertex>(vertex: start, cost: 0, estimate: heuristic(start, target)))
while !open.isEmpty {
guard let node = open.remove() else {
break
}
while !open.isEmpty, let node = open.remove() {
Copy link

Choose a reason for hiding this comment

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

for better readability, please split !open.isEmpty and let node = open.remove() into two lines.

Copy link
Member

Choose a reason for hiding this comment

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

I actually like this change. 😄 Having it all on one line would be my preference.

costs[node.vertex] = node.cost

if (node.vertex == target) {
Expand Down
8 changes: 4 additions & 4 deletions Huffman Coding/Huffman.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ extension Huffman {
while queue.count > 1 {
// Find the two nodes with the smallest frequencies that do not have
// a parent node yet.
let node1 = queue.dequeue()!
let node2 = queue.dequeue()!
guard let node1 = queue.dequeue(), let node2 = queue.dequeue() else { return }
Copy link

Choose a reason for hiding this comment

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

for better readability, please split node1 and node2 into two lines.

Copy link
Member

Choose a reason for hiding this comment

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

Again, no need to do this, plus in my opinion it doesn't actually improve readability.

Copy link
Author

@Shahn-Auronas Shahn-Auronas Mar 10, 2021

Choose a reason for hiding this comment

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

It's not strictly needed, especially if you are not linting (where a force-unwrap rule would fail your build). I understand that this is not production code, but it's still good coding style to not force unwrap unless you are testing your code and, even then, you have XCTUnwrap.

Copy link
Member

Choose a reason for hiding this comment

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

Force unwrap is perfectly acceptable when it cannot possibly fail. Writing code that handles errors that can never occur is more dangerous because it can hide subtle bugs or cause people to insert subtle bugs later (i.e. it adds complexity that doesn't need to be there).

Copy link
Author

Choose a reason for hiding this comment

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

Not sure I follow the complexity argument in using guard statements. I take your point on force unwrap when it's impossible to fail, ergo my point above on tests. My point was good coding style - i.e., not getting in the habit of force unwrapping when you can easily guard. @snooky23 matter of taste, but I don't disagree with you.

Copy link
Member

@hollance hollance Mar 13, 2021

Choose a reason for hiding this comment

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

When the guard fails, you return from the method. This can never happen, but you've added logic that makes it seem like returning early from the method is allowed. But it isn't, since there is logic that happens after the while loop. Your change doesn't introduce a bug by itself because the return will never happen, but it makes it appear as if it's OK to exit from the method inside the while loop, which is not OK. Hence, you've added complexity that wasn't there before, and the potential for bugs to be introduced because the error handling path of your code is incorrect. It would be better to do a fatalError instead of a return, but that is also more complex than just force unwrapping.


// Create a new intermediate node.
var parentNode = Node()
Expand All @@ -115,8 +114,9 @@ extension Huffman {
}

// The final remaining node in the queue becomes the root of the tree.
let rootNode = queue.dequeue()!
root = rootNode.index
if let rootNode = queue.dequeue() {
root = rootNode.index
}
}
}

Expand Down