I find the use of guard
very helpful both when I'm writing and reading code and think I would find the cognitive cost to be higher if any let
or var
assignment could potentially be an early exit.
I realize that indentation, spaces between lines, putting else
clauses on the same or different lines is a matter of personal preference. But I think that some approaches make guard
statements read with more continuity than others.
In the example provided, I would probably group the guard
statements together, so that all of the things that need to be successful to proceed happen in one conceptual run of code.
guard let store = sharedNotesStore else { throw Error.noSharedNotesStoreAvailable }
guard let data = section.propertyDictionary.json else { throw Error.serializationFailure }
guard let section = section(withIdentifier: noteIdentifier, data: data) else { throw Error.noSectionFoundForNote }
let blobs: [SharedNote.Blob] = [.init("ABC")]
let key = UUID().uuidString
let sharedNote = SharedNote(store: store, section: section, key: key, blobs: blobs)
In the midst of a method, I also tend to add a line of whitespace before a guard
statement, so that it stands out as a precondition for proceeding.
For me, one of the benefits of guard
is that I know immediately that this is code that will exit early in some way. Even if the else
clause is on the same line as shown in the example code, you are certain that you will find it at end of the line by seeing that initial guard
keyword.
With the proposed change, for longer lines, you need to scan pretty far to the right to discover that this line of code can have bigger consequences than simply assignment. For each and every let
or var
declaration, you never know if maybe there's an early exit without scanning almost the entire line.
let section = section(withIdentifier: noteIdentifier, data: data) else { throw Error.noSectionFoundForNote }
I also think that if let
and guard let
both communicate that optional binding is occurring and that what is happening is not simply an assignment.
I can absolutely see the lack of flow in the code example provided, but I think this proposed change would reduce the clarity of all variable and constant declarations by making them ambiguous until the developer scanned the entire line. So, I am -1 for this proposal.