Tutorial outline

Unit 1

  1. 01Getting started
  2. 02Names and functions
  3. 03Control
  4. 04Higher-order functions
  5. 05Environments and closures
  6. 06Functional abstraction
  7. 07Recursion
  8. 08Tree recursion

Unit 2

  1. 09Sequences
  2. 10Dictionaries, sets, and tuples
  3. 11Optionals
  4. 12Structures and enumerations
  5. 13Linked lists and trees
  6. 14Mutation and value semantics
  7. 15Classes and inheritance
  8. 16Protocols and generics
  9. 17Iterators and lazy sequences
  10. 18Efficiency and memoization

Unit 3

  1. 19Algebraic data types and pattern matching
  2. 20Writing an interpreter
  3. 21Error handling
  4. 22Concurrency with async and await
  5. 23Testing
  6. 24Building a Swift package

Getting started

Run your first Swift program, evaluate expressions the way the computer does, and meet the two kinds of error you will see all course.

CS61A
Welcome · Composing Programs 1.1

CS61A opens with a claim: the most important idea in programming is abstraction, giving a name to something complicated so you can stop thinking about its details. This tutorial follows that course lecture by lecture, in Swift. Before abstraction, though, we need a program that runs.

Running Swift

Swift runs on macOS, Linux, and Windows. On a Mac, installing Xcode or the Command Line Tools gives you swift; on other systems, use the installer from swift.org/install. Check it worked:

swift --version

Save this line in a file called hello.swift:

print("Hello, world!")

Then run it:

swift hello.swift

That one line is a complete program. There is no main function to write and nothing to import: code at the top level of a file is where the program starts. Every lab in this tutorial works the same way. Put the code in a .swift file and run it with swift.

Expressions

A program is built from expressions, pieces of code that produce a value. The simplest expressions are values themselves:

print(2026)
print(3.14)
print("Swift")
print(true)

Operators combine values into bigger expressions. Arithmetic works as you expect, with one surprise: when both sides are whole numbers, / throws away the remainder, and % gives you the remainder.

print(7 + 2)    // 9
print(7 / 2)    // 3
print(7 % 2)    // 1
print(7.0 / 2)  // 3.5

What would Swift print?

print(17 / 5)
print(17 % 5)

Type Error if running it would crash. For several lines of output, put each on its own line.

Show answer and explanation

Answer3\n2

17 / 5 divides two integers, so the result is the integer 3; the remainder, 17 % 5, is 2. Each print writes its own line.

Call expressions

A call expression applies a function to arguments. max and min come with Swift:

print(max(3, 9))           // 9
print(min(max(1, 5), 3))   // 3

CS61A’s rule for evaluating a call expression works for Swift too:

  1. Evaluate the function being called.
  2. Evaluate each argument, left to right.
  3. Apply the function to the argument values.

Arguments are evaluated before the call, so nested calls work from the inside out. In min(max(1, 5), 3), max(1, 5) becomes 5 first, and then min(5, 3) is 3.

What would Swift print?

print(max(2, min(8, 4), 3))

Type Error if running it would crash. For several lines of output, put each on its own line.

Show answer and explanation

Answer4

min(8, 4) is evaluated first and gives 4, so the call becomes max(2, 4, 3), which is 4. max accepts any number of arguments.

print can take several arguments too. It writes them separated by spaces:

print("Swift", 6, true)   // Swift 6 true

Types

Every value in Swift has a type. 2026 is an Int, 3.14 is a Double, "Swift" is a String, and true is a Bool. Swift checks types before your program runs, and it never converts between them silently.

What would Swift print?

let whole = 1
let fraction = 2.5
print(whole + fraction)

Type Error if running it would crash. For several lines of output, put each on its own line.

Show answer and explanation

AnswerError

whole is an Int and fraction is a Double, and Swift will not add them without being told how. The program does not compile. Writing Double(whole) + fraction makes the conversion explicit and prints 3.5.

A number written directly in the code is more flexible: in 1 + 2.5, Swift reads 1 as a Double because that is the only way the expression makes sense. The strictness applies to values that already have a type.

Strings can include values with interpolation: write \( and ) around any expression inside a string.

let language = "Swift"
let version = 6
print("\(language) \(version) was released with a new language mode.")

Two kinds of error

Swift reports mistakes at two different times.

  • A compile-time error stops the program before it starts. Type mismatches, misspelled names, and missing punctuation are all caught this way. Nothing runs, not even the lines before the mistake.
  • A runtime error happens while the program is running, when it tries something impossible. Swift stops the program immediately rather than continuing with a wrong value.
let scores = [90, 85, 77]
print(scores[3])   // there is no fourth score

The array has positions 0, 1, and 2, so asking for position 3 stops the program at run time. In “What would Swift print?” questions, the answer to both kinds of failure is Error.

Put the lines in order

Put these lines in order so the program prints 15.

  1. let b = a * 2
  2. print(c + 3)
  3. let a = 3
  4. let c = b + a * 2

Show the correct program
let a = 3
let b = a * 2
let c = b + a * 2
print(c + 3)

Lab 0: Getting started

Labs are where you write code. Create a file for each lab, write your answers, and run it with swift. Each solution ends with assert checks: lines that stop the program if a result is wrong, and do nothing if it is right. They play the role of CS61A’s doctests.

Q1: Your setup

Run swift --version and then swift hello.swift with the program above. If both work, you are ready for the rest of the course.

Q2: Seconds in a week

Write an expression for the number of seconds in a week, using only multiplication, and print it.

Show solution
let secondsPerWeek = 7 * 24 * 60 * 60
print(secondsPerWeek)
assert(secondsPerWeek == 604_800)

Underscores in a number literal are ignored by Swift; they only make large numbers easier to read.

Q3: Fix the program

This program is meant to print the average of three test scores, 84.0, but it does not compile. Find the problem and fix it without changing the scores.

let total = 90 + 85 + 77
let count = 3.0
print(total / count)
Show solution

total is an Int and count is a Double. Convert one of them:

let total = 90 + 85 + 77
let count = 3.0
let average = Double(total) / count
print(average)
assert(average == 84.0)

Making count an Int instead would compile too, but 252 / 3 would then use integer division. It happens to divide evenly here; with other scores it would silently drop the fraction.

What’s next

Next lesson: naming values with let and var, and defining your own functions.