Using value and reference types

The Swift Programming Language by Apple Inc. has a section on comparing structs (value type) and classes (reference type) and how to prefer one over the other. It is highly recommended to read that section to understand why we prefer one over the other. Although we touched on the topic briefly in Chapter 1, Getting Started With Functional Programming in Swift, we will explore this topic further as the distinction between reference and value types is very important in FP.

In OOP, we model real-world objects as classes and interfaces. For instance, to model an Italian restaurant with different types of pizzas, we may have a Pizzaclass and subclasses of it such as Margherita, Napoletana, or Romana. Each of these pizzas will have different ingredients. Different restaurants may make them slightly differently, and whenever we read their recipes in different books or websites, we may understand it differently. This level of abstraction enables us to refer to a specific pizza without caring about how other people really imagine that pizza. Whenever we talk about that pizza, we do not transfer it, we just refer to it.

On the other hand, in our Italian restaurant, we will need to provide bills to our customers. Whenever they ask for the bill, we are going to provide real information about quantity and prices. Everyone has the same perception about quantities, prices in dollars, and, in fact, values. Our customers can calculate the invoice total. If our customers modify the bill, it is not going to modify the source that we used to provide the bill. No matter whether they write something on the bill or spill wine on it, the value and bill total amount is not going to change.

The preceding example presents a simple real-world usage of reference versus value types. Value types and reference types have their own usages in the Swift programming language and in web, mobile, or desktop application programming.

Value types enable us to make architectures clearer, simpler, and more testable. Value types typically have fewer or no dependencies on the outside state, so there's less that we have to consider when reasoning about them. Also, value types are essentially more reusable because they are interchangeable. As we use more value types and immutable entities, our system will become easier to test and maintain over time.

In contrast, reference types are acting entities in the system. They have identity. They can behave. Their behavior is often complex and hard to reason about, but some of the details can usually be represented by simple values and isolated functions involving those values. Reference types maintain a state defined by values, but these values can be considered independently of the reference type. Reference types perform side effects such as I/O, file and database operations, and networking. Reference types can interact with other reference types, but they generally send values, not references, unless they truly plan to create a persistent connection with the external system.

It is important to use value types (enums, tuples, or structs) as much as possible unless we need to create a shared mutable state. There are cases where we have to use classes. For instance, when we work with Cocoa, many APIs expect subclasses of NSObject, so we have to use classes in these cases. Whenever we need to use classes, we avoid variables; we define our properties as constants and avoid exposing any APIs that can alter states.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset