What your Swift code is really saying
Swift is a great language to express intent (far better than Java and Objective-C). By choosing the correct keywords, we can better express our intent of our logic for both compilers and other programmers to read and understand. Let’s take a look at the most common keywords in Swift and see what they really mean… ironically emphasised using the power of emoji.
😀
let vs var
Mutability
let foo: Int
😎 Inert. Won’t change. Deal with it! The only thing that can set this is the thing that initialised it. Enjoy the simplicity.
var foo: Int
😥 This will change over time. Anyone with access may change this at any time. Watch out for race conditions.
protocol, struct, enum, final class vs class
Value types or Subclassing
protocol AppleType {👯 This behaviour is applicable to one or more types in the code base, and can be used to decrease the surface area of an object or API.
struct Apple {💃 This is a value; is passed from object to object, function to function; is not observed.
enum Apple {👭 This is a value; is one of a finite set of value types; is passed from object to object, function to function; is not observed.
Personal opinion: Switching on an enum outside of the enum type is a code smell.
final class Apple {🙅 This is not just a value; may be shared; may be observed by more than one; is probably a subclass of an Apple class.
class Apple {🙍 This is complex; not just a value; may be shared; may be observed by more than one; is subclassed somewhere (thus, this state and logic is used somewhere else); is probably a subclass of an Apple class.
private vs private(set) vs internal vs public
Helpers or API
private var items: [Item]
👶 This is a helper member. Refactoring will only effect this file.
private(set) var items: [Item]
💪 This is API to the rest of the product, or is conforming to a protocol. All mutations happen within this file.
var items: [Item]
🙄 This is API to the rest of the product, or is conforming to a protocol, or is dispatched to the Objective-C runtime (for methods).
public var items: [Item]
😅 This is API for this framework, or is conforming to a public protocol.
static vs class vs *none*
Namespaced Freedom or Instance-dependent
static func sum(array: [Int]) -> Int
🤗 No dependency on instance state; only closes over global state. I think of these as a namespaced free function. Calling this is most predictable.
class func sum(array: [Int]) -> Int
😳 Same as above: namespaced free function. Sadly, it expects and encourages sub-classing to trick the implementation of something somwhere.
func sum(array: [Int]) -> Int
😑 This function needs to close over global and instance state.
guard vs switch vs if
Precondition or Branches
guard num > 0 else {✋ This is a precondition to the following imperative code.
switch num {🖖 The code branches on one or more related conditions, and must be exhaustive.
Personal opinion: default is a code smell.
if num > 0 {🤕 The code branches on one or more unrelated conditions, and does not need to be exhaustive.
Bonus Round!
lazy var apple = getApple()
🤑 Deferring expensive calls that may not get used in the life cycle of this object, or requires instance state to perform initialisation. However, this can’t be immutable (see the meaning of var above).
var apple: Apple?
😶 Having no value is a valid and meaningful state to be in, and should be handled.
var apple: Apple!
🙃 Is expected after initialisation but before usage. WTF? No type safety. 100% code smell.
private static func sum(array: [Int]) -> Int
😂 If a method is private and independent of state, it sounds like a free function. Move it out of the class. This applies to private static values as well.
Note:
All immutable, static, or private keywords will always improve compile times and minimise future refactoring effort.
Conclusion
Every keyword carries with it an intent. Swift is a wonderfully expressive language. Please use the vocabulary that is provided by your language as best you can to write readable, well-expressed code.
I’m passionate about using the correct words (in English and Swift). I hope this helps you use the correct words as well. 😁
If you liked this, read my other rants and follow me on Twitter.