Swift: Don’t do that

bad-hair-day---alpaca-1395419-m

The assorted list:

Don’t add code cruft. Avoid parentheses around conditions in if-statements or with the return keyword. Don’t add semicolons except where syntactically demanded in statements or to separate statements on the same line. (Do skip parens, semicolons, other relics of ObjC life)

Don’t use ALL_CAPS; use camelCase. (Do camelCase allTheThings.)

Don’t fight type inference. Use enumeration prefixes, self-references, and class names (with constructors) only when necessary or to clarify coding intent. (Do allow type inferencing to do its thing. It makes everything prettier, more readable, and self-documenting.)

Don’t use var when let is appropriate, especially for properties. The compiler better optimizes let statements for items whose values will not change during their lifetime. For example, Apple writes, “It is good practice to create immutable collections in all cases where the collection does not need to change. Doing so enables the Swift compiler to optimize the performance of the collections you create.” (Do prefer let over var where appropriate)

Don’t use classes when structs will do. Use classes if you want reference types. Use structs if you want value types. You can add functionality to both (and to enumerations) in Swift. When in doubt, err on the side of value types. If your construct doesn’t have a life cycle, or two constructs with similar values should be considered as the same thing, use a struct. (Do take advantage of Swift structs. They’re neat.)

Don’t use fallback values when what you really want are optionals. If you’re working hard to avoid nil checks, you’re doing Swift wrong. (Do use optionals. Use them well. Love them. Embrace the nil and the if let.)

Don’t abuse !. Justify each exclamation point and forced unwrap in your code. If-let offers better and safer code, and 1.2 introduced let cascades. (Do prefer if-let to forced unwrapping whenever possible.)

Don’t forget access controls, especially for top-level definitions. Access controls ensure your code can be re-used and modularized. (Do annotate your code with access controls.)

Don’t be unnecessarily verbose. Use inferred get clauses (for properties), anonymous arguments (e.g. $0, skipping the type in bits for closures), etc to clean up your code. (Do be concise. I get that I’m in the minority here but $0 is beautiful.)

Don’t use Allman1TBS is your Swift style. (Do use 1TBS over Allman.) Personally, I love Allman and prefer it but Swift fights the Allman. If you’re fighting the language, you’re doing it wrong. Note: If you hate else on the same line as closing braces, Stroustrup braces and Compact Control Readability style are acceptable alternatives.

Don’t avoid Foundation and Cocoa. At the same time, use Swift native types whenever possible. (Do use Swift native types where possible)

Don’t use CGPointMake(). Prefer Swift constructors and initializers over legacy ones. (Do prefer Swift constructors over legacy constructors)

Don’t use unnecessary variables. The wildcard expression (_) ignores values during assignments. Use it to skip items that are not referenced in the called scope, e.g. let (status, _) = GetInfo() or for _ in 1…5 {//do something 5 times} (Do use _ liberally.)

Don’t fear uppercase. Use TitleCase for types and enum variants. (Do uppercase where appropriate. Further discussion here. Apple historically used camelcaps for functions. Because of language inferencing, uppercase differentiates scope at a glance. It makes clear whether items are intended as a function or a method. Since you can write either self.doSomething() or doSomething() in a containing scope, using doSomething() vs DoSomething() adds useful semantic context. )

Gist: here

Update: Added “do” versions to the don’ts.

Thanks, Kevin Ballard

p.s. Thank you to everyone who helps support the blog by visiting advertisers and purchasing books

6 Comments

  • “Use enumeration prefixes”, Is it not so verbose to use enumeration name every time in switch case?

    • I put everything as a “don’t do this”, so that line reads “use enumeration prefixes only when…”

      • My mistake – too long sentence)

  • There a lot of great points here, but I would rather see a list of Dos than Do Nots. We don’t want to intimate new Swift programmers and make them always worry about doing something wrong. I think it would be better to phrase it as a list of things that all Swift programmers can do better (It would be all the same points but listed in the positive instead of the negative). Great list though.

  • Why do you say “Swift fights the Allman”? I haven’t found that at all.

  • I’m also using Allman with Swift, happily… but also completely defiantly. Disappointing to see you cede our holy war to the style of the savages, Erica :-/