Introduction to Swift

October 27, 2014

Swift is a brand-new programming language designed by Apple for creating OS X and iOS applications. It was introduced in June of this year at Apple’s developer conference, and was released for OS X this month.

Swift is interesting and exciting because its syntax looks and feels like that of a high-level scripting language like Ruby or Python, but it’s actually a compiled language with static, strong types and can be mixed with C and Objective-C code. You can also identify some distinctly functional paradigms in Swift, like currying and higher-order functions. If that wasn’t enough, you’ve also got the object-oriented functionality (e.g., classes, inheritance, and generics) of languages like Java and C++.

This article is intended to be a very quick introduction to Swift for programmers that already know a “standard” programming language as low as C or Java, and also for programmers who are only familiar with languages as high-level as Python. For each language feature Swift offers, I’ll summmarize the feature briefly and show examples of its Python, C, and Java analogues.

Types

In Swift, there’s a notion of named and compound types. You’re already familiar with named types: those are integers, strings, and arrays. (Swift knows them as Int, String, and Array.) Compound types are product types or function types. For example, the compound type (Int, Int) is a tuple of two integers, and Int -> String -> Int is the type of a function that takes an integer and a string and returns an integer.1

Here’s a table of example types in Swift, for your reference:

Type Meaning
Int integer (i.e., int in C-like languages)
Double double-precision, floating-point number
Float single-precision, floating-point number
Bool Boolean value (singletons: true or false)
String string of characters (with full Unicode support)
Character one unicode character (use double-quotes as with strings)
Array standard array, with syntax like JavaScript
[Int] “shorthand” type for array of integers
Dictionary standard key-value storage, with syntax like Objective-C
[Int: Bool] “shorthand” for dictionary with integer keys and Boolean values
(Int, String) a product type of two values: an integer and a string
Int -> Int -> Int a function taking two integers and returning an integer
Void what a function returns when it doesn’t return anything

Variables

As with most Swift features, variable declaration is most like Python or Ruby. In this case, its use of the var keyword makes it more like JavaScript. However, the let keyword can also be used to introduce a variable that doesn’t vary — a constant.

In Swift, all variables are typed, but you don’t need to be explicit about a variable’s type in most cases, since the compiler can figure it out. Below are examples of varying and constant variables where I’ve been lazy and specific about types.

// standard variable (a type of String is inferred by the compiler)
var name = "Dave"

// variable with an explicit type annotation
var otherName: String = "Cody"

// constant variable: enforced by the compiler
let number = 6

// constant variable with an explicit type annotation
let otherNumber: Int = 15
Variables in Swift
name = "Dave"
otherName = "Cody"      # Python does not have type annotations
number = 6              # Python does not have constants, either
otherNumber = 15
Variables in Python
// all variables in Java must have explicit types
String name = "Dave";
String otherName = "Cody";
final int number = 6;
final int otherNumber = 15;
Variables in Java
const char *name = "Dave";
const char *otherName = "Cody";
const int number = 6;
const int otherNumber = 15;
Variables in C

Strings

In Swift, easy concatenation with the + operator is supported. Strings can be concatenated with other strings or characters. Two characters can be concatenated into a string. Think of Python, but with an explicit Character type if you end up needing it.

var string = "abc"              // no explicit type info. needed
var char: Character = "z"       // using double quotes with characters
Strings and characters in Swift
string = "abc"
char = "z"                      # Python has no character type
Strings in Python
String string = "abc";
char ch = 'z';              // char is reserved word; need single quotes
Strings and characters in Java
const char *string = "abc";
char ch = 'z';
Strings and characters in C

String formatting

In Swift parlance, creating a string containing the values of variables is called string interpolation. Just like the format() method in Python strings, you don’t have to specify the type of the variable going into the format string. Instead, you use a special escape sequence and specify the name of the variable you want to place into the string. If you’re not familiar with Python, it’s similar to Java’s format() method of the String class and the C sprintf() function.

let x = 1, y = 2, z = 3
var string = "\(x) and \(y) and \(z)"
String interpolation in Swift
x, y, z = 1, 2, 3
string = "{} and {} and {}".format(x, y, z)
String formatting in Python
int x = 1, y = 2, z = 3;
String string = String.format("%d and %d and %d", x, y, z);
String.format() in Java
// need include to use sprintf()!
#include <stdio.h>
...
char buf[256];
int x = 1, y = 2, z = 3;
sprintf(buf, "%d and %d and %d", x, y, z);
sprintf() in C

Collections

Swift has built-in array and dictionary types, with special syntax. The syntax comes from Objective-C. If you don’t know Objective-C, the array syntax looks like JavaScript. If you don’t know JavaScript, well, just take a look at the example below.

Arrays can only contain values of one type. Dictionaries are similar: all keys must have the same type, and all values must have the same type.

var array = [1, 2, 3, 4]
var dict = ["a": 1, "b": 2, "c": 3, "d": 4]

// note: we could have added type annotations (see below)
var array2: [Int] = [1, 2, 3, 4]
var dict2: [String: Int] = ["a": 1, "b": 2, "c": 3, "d": 4]
Arrays and dictionaries in Swift
# Python has no array type, but it does have lists
# lists can hold values of any type, however
array = [1, 2, 3, 4]

# Python dictionary keys can be of any type, as long
# as the type is hashable, and values can be of any type
dict = {"a": 1, "b": 2, "c": 3, "d": 4}
Lists and dictionaries in Python
// need import statement for dictionary!
import java.util.HashMap;
...
int[] array = {1, 2, 3, 4};
HashMap<String, Integer> dict = new HashMap<String, Integer>();
dict.put("a", 1);
dict.put("b", 2);
dict.put("c", 3);
dict.put("d", 4);
Built-in arrays and HashMap in Java
int array[] = {1, 2, 3, 4};
// dictionary type is not available in C; pick your favorite library
Arrays in C

Iteration

In Swift, standard while and for loops have shed their pesky parentheses. Swift also has for ... in (a.k.a., foreach) loops.

It’s worth noting that Swift has do ... while loops as well, and the syntax follows naturally from the while loop syntax. Python, however, does not have support for do ... while loops. If you know Python and you’re new to Swift, you can investigate how do ... while loops work in C or Objective-C first.

Swift also has support for using for ... in with dictionaries. Python has this, as long as you use the items() method of the dictionary. Java has this, too, but it’s a bit clunky — you have to deal with the Map.Entry interface.

var a = 3
while a > 0 {
    a -= 1                      // Swift has -= operator...
}

for var i = 0; i < 3; i++ {     // ...and has ++ and -- operators
    println("boop!")
}

var array = [1, 2, 3]
for i in array {                // does what you'd expect
    println(i)
}
while, for, and for ... in loops in Swift
a = 3
while a > 0:
    a -= 1

for i in range(3):          # Python has no C-style for loop
    print("boop!")

array = [1, 2, 3]
for i in array:
    print(i)
while and for ... in loops in Python
int a = 3;
while (a > 0) {
    a -= 1;
}

for (int i = 0; i < 3; i++) {
    System.out.println("boop!");
}

int[] array = {1, 2, 3};
for (int i : array) {
    System.out.println(i);
}
while, for, and foreach loops in Java
// need include for printing to standard out!
#include <stdio.h>
...
int a = 3, i = 0;

while (a > 0) {
    a -= 1;
}

for (i = 0; i < 3; i++) {
    printf("boop!\n");
}

// C has no more complicated loops
for and while in C

Ranges

Ranges are a feature that Swift shares with Python only. Java and C don’t have this feature. A range is a bit of syntax that represents a sequence of values (you can think of it as an array), where each value isn’t necessarily stored explicitly. It’s often used in for ... in loops, where rather than coming up with initial values and stopping conditions for a for loop, you can just draw values from a range.

Swift has two range operators: the closed range operator, three full stops (...), which takes two integers: a lower and upper bound, and produces a range that includes both the lower and the upper integers in the range.

The half-open range operator (..<) creates a similar range, but leaves out the upper value from the range.

for i in 1...4 {    // prints numbers between 1 and 4, including 4
    println(i)
}

for i in 0..<8 {    // prints numbers between 0 and 8, not including 8
    println(i)
}
A closed and half-open range in Swift
for i in range(1, 5):
    print(i)

for i in range(8):
    print(i)
Ranges in Python

Tuples

Tuples are another feature that Swift shares with Python. A tuple is a grouping of two or more values together into one value, such that the component values stay together in order. Unlike Python tuples, Swift tuples can have names.

To get the values out of a tuple, you can access them by index, by name, or deconstruct them with an assignment statement, as in Python.

var tup = (1, "two", false)
println(tup)                    // prints (1, two, false)

// deconstructing the tuple into three variables
var (a, b, c) = tup
println(b)                      // prints two
println(tup.1)                  // also prints two

// named elements
var tup2 = (elementOne: "abc", elementTwo: "xyz")
println(tup2.elementOne)        // prints abc

// changing element of a tuple
tup2.elementOne = "ABC"
println(tup2.elementOne)        // prints ABC
Tuples in Swift
tup = (1, "two", False)
print(tup)                      # prints (1, 'two', False)

a, b, c = tup
print(b)                        # prints two
print(tup[1])                   # also prints two

# tuples in Python cannot have names
# note also that Python's tuples cannot be reassigned:
# tup[1] = "something" would fail
Tuples in Python

Optionals

Optionals are a Swift-only feature, though functional programming languages have structures like it (e.g., the Maybe type in Haskell).

An optional type is a normal type with some extra information: whether the value is present or absent. You can use optionals when a function might not always return a meaningful value, and you might need to check for the absence of a value later on. (In this sense, it’s similar to checking for null in Java, NULL or similar in C, or None in Python. However, these are “special” values specific to a certain type — you can’t check an int in Java for null.)

Take, for example, the following Swift code, taken from Apple’s documentation for optionals:

let possibleNumber = "123"
let convertedNumber = possibleNumber.toInt()

Here, toInt() has a type of Int? which means it might return an integer – or it might not. If toInt() doesn’t return an Int, it gets the value nil, which can only be used for optionals. You can use an if statement to check for nil:

if convertedNumber != nil {
    println("convertedNumber contains some integer value.")
}

If you wanted to actually print the converted number in this case, you’d need some special syntax to “unpack” the converted number from the optional variable. That syntax is the ! operator:

if convertedNumber != nil {
    println("convertedNumber has an integer value of \(convertedNumber!).")
}

Given that possibleNumber is "123", the code above would output the following:

convertedNumber has an integer value of 123.

To make a function return an optional value, just stick a ? at the end of its return type.

Functions

Functions in Swift have a modern feel, but are functionally similar to their Objective-C or C elders. Like Objective-C, functions can have named and external parameters.

Function parameters must have types, but the type of a function can be omitted. In that case, the function returns Void.

func find(array: [Int], val: Int) -> Int? {
    for i in 0..<array.count {
        if array[i] == val {
            return i
        }
    }

    return nil
}
Function definition in Swift
# note the lack of type annotations
def find(array, val):
    for i in range(len(array)):
        if array[i] == val:
            return i                # returns type of int
    else:
        return None                 # returns type of NoneType
Function definition in Python
public static int find(int[] array, int val) {
    for (int i = 0; i < array.length; i++) {
        if (array[i] == val) {
            return i;
        }
    }

    // can't return a special value here!
    // we must return an int or throw an exception
    return -1;
}
Method definition in Java
// note: we need to know the length beforehand
int find(int array[], int len, int val)
{
    int i;
    for (i = 0; i < len; i++) {
        if (array[i] == val) {
            return i;
        }
    }

    // same as in Java: can't return a special value here!
    return -1;
}
Function definition in C
  1. If you’re a Haskell fan like me, you might be jumping for joy. Did you know that Swift also has curried functions