Note: This article was originally submitted to DZone anonymously.
Swift arrived just at the right time for me; as much as HTML5 was gaining popularity for delivering web applications, I really wanted to work with a language that had the strictness ofActionScript. I had also started using Flex to target mobile and desktop, and native applications seemed a better solution for enterprise software than delivering via a browser.
Swift offered a static and strongly-typed language and access to the huge and diverse universe of Apple’s different frameworks for iOS and OS X. This article discusses some of the highlights of Swift from my perspective.
Optionals and Strong Typing
Swift’s immediate difference from any other language I’ve worked with is its use of optionals. Whereas is other languages, a developer can declare a variable but not insatiate or construct it (i.e. that variable’s value is null), by default, this isn’t possible in Swift. Ostensibly this sounds odd, but in real life, this strictness prevents “null pointer exceptions” which, certainly in ActionScript, are the source of the vast majority of run time errors.
Swift uses type inference to enforce type safety. Developers don’t need to explicitly define the type of a variable when declaring it; the compiler is smart enough to infer that from context. This system works incredibly well, and code simply won’t compile if, for example, I try to populate an integer value with a string.
Functions as First-class Types
Although languages such as ActionScript can pass functions around as variables, the “signature” of those functions isn't enforced. For example, I may pass a callback method to an asynchronous function, which it will execute after it’s completed. There’s no way in ActionScript of ensuring the arguments my callback method requires are set by the asynchronous code.
Swift’s functions are properly defined types with their arguments and return types fully defined. Furthermore, Swift functions can return a function as its value.
Enumerations & Exhaustive ‘Switch’
Enumerations are sets of objects that can restrict variables to certain values. For example, you may have a variable that relates to points on the compass. Rather than allowing that variable to be, for example, a string that could contain any value, Swift allows us to define a fixed set, “North”, “South”,“East” and “West” to restrict the possible values.
While enumerations aren’t unique to Swift, its strictness handling those is outstanding. Many programs include “switch”statements to select different actions depending on the value of a given variable. It’s very easy to construct a switch statement based on an enumeration and forget to add a certain case. Swift implements “exhaustive switching,” which prevents the program from compiling if the developer overlooks a case statement for any of the enumerations.
Enumerations in Swift can also have “associated values.” In the case of our compass point examples, each enumeration could also have an associated numeric value for distance.
However, these values can be different types with different enumerations, so an enumeration expressing geographic locations, for example, may store geolocation coordinates as a two component vector and zip codes as integers.
Although all this strictness of optionals, strongly-typed functions, and exhaustive switch statements may sound like a hindrance to developers, the additional requirements to get a Swift application to actually compile prevents a multitude of runtime errors—the errors our users would experience.
How many times have you written a function—let’s say one that swaps the values of two variables—that acts upon a certain data type only to have to rewrite it for another data type. With the example of swapping the values of two items, the mechanics are the same, only the types of the two items have changed.
With Generics, Swift allows developers to create single, reusable functions that act upon a variety of different datatypes and avoid code duplications.
Extensions & Operator Functions
Swift allows developers to extend the functionality of existing types without the need for subclassing them though“retroactive modeling” or, more simply, “extensions.” For example, if your code is littered with littles bits of math converting celsius to Fahrenheit or degrees to radians, it’s very little effort to write an extension to one of the numeric types, Float or Double, and add a conversion method. The method can even be used on literals, so 123.0.degreesToRadians() would be valid syntax.
Another way developers can extend Swift is by defining their own “operator functions.” For example, the operator “==” may not work for a custom class that contains a number of fields. A customer type might need an equivalence operator to ensure the customer name, address fields, and website address all match. Swift allows the creation of a custom implementation of “==“ that looks at all the fields.
Operator functions can not only be infixed (such as “==” which sites between two arguments), but prefixed and postfixed to appear either before or after a target. This means a developer could create their own version of the increment operator (“++”) to act upon a custom class.
Many languages support protocols, sometimes referred to as interfaces. At WWDC 2015, Apple was keen to promote a new programming paradigm, Protocol Oriented Programming with a new feature in Swift, Protocol Extensions.
Protocol Extensions allow developers to implement default functionality for all classes or structures, then conform to a particular protocol. For example, a class that implements a Sortable protocol might require a sort() method. A protocol extension could provide a default sort algorithm (maybe using generics) that Sortable implementations could “get for free.” If a developer so wished, they could override that default implementation to write a domain specific or better-performing implementation of sort().
Features such as generics, extensions, and custom operators make Swift an amazingly extensible language. Custom frameworks that solve solutions for particular domains can be transparently integrated and complex logic can be hidden from developers.
New iOS devices have amazingly powerful GraphicalProcessing Units (GPUs). Although not specific to Swift, Apple’sMetal framework offers an easy to learn C++ based language and an easy API to harness that processing power. Metal supports both 3D rendering through vertex and fragment shaders and compute shaders for parallel computation.
Compute shaders allow data-intensive work such as physics simulations or deep learning to be delegated to the GPU while the CPU is free to concentrate of tasks such as user interface management, keeping the application responsive.
Community & Evolution
One of the great strengths of Swift – and one that Apple themselves may not have foreseen — is the amazing community that's grown around it. Across the world, there are countless meetups and conferences, and on the internet there plenty of people blogging about Swift, sharing their code and helping each other out on Twitter and Stack Overflow.
Apple hasn’t stood still with the language either; they are obviously listening to the developer community and continue to work on new language features and optimization. In the most recent release of Swift, Apple introduced functionality such as a new guard statement for control flow and error handling.
Now that Apple has open sourced the Swift language, developers can contribute to the language; new platforms, such as Linux, can be targeted; and there is increased visibility as to its evolution.
Swift is a new language, but it has grown at a phenomenal pace. Its strictness with optionals and data types may feel like a developer burden at first, but that extra effort helps overcome many runtime issues and prevent your users from experiencing unexpected issues caused by common issues such as null pointer exceptions. With Swift open sourced and companies such as perfect.org already vending a server-side release of Swift, the promise of a single safe, expressive, and fast language