Before we go on, here's some tips for users of other programming languages this year:

  • Rust supports very similar syntax to Swift
  • Java, C#, and C++ support similar syntax to each other. In these languages, the return type is specified at the beginning rather than at the end.
  • Furthermore, Rust and C++ make use of additional symbols such as *, **, and & for pointers. It is your responsibility to learn how pointers are used in your chosen language

Functions can accept multiple parameters, and each parameter must have a specified type.

func greet(name: String, age: Int) -> String {
    return "Hello, \(name)! You are \(age) years old."
}

let message = greet(name: "Alice", age: 17)
print(message) // Output: Hello, Alice! You are 17 years old.

  • Create a function introduce(name:age:city:) that takes a name, age, and city, returning a formatted introduction string.
  • Call the function and print its result.

By default, parameter names must be used when calling a function:

func multiply(number1 a: Int, number2 b: Int) -> Int {
    return a * b
}

let product = multiply(number1: 3, number2: 5)  // Must use names!
let product2 = multiply(3, 5)  // Swift refuses to compile this code

  • Write a function subtract(minuend:subtrahend:) that subtracts the second number from the first.
  • Call it using named parameters and print the result.

If we don’t want to require parameter names at the call site, we use _:

func subtract(_ a: Int, _ b: Int) -> Int {
    return a - b
}

let difference = subtract(10, 4)  // No parameter labels needed

Don't use _ excessively to match familiar Python-style behaviour. This would NOT follow Swift conventions. Following conventions is a Kaiaka/M criteria.

  • Convert the subtract(minuend:subtrahend:) function from Task 4 to allow omission of parameter names.
  • Call the function and print the result.

In Swift, functions can return values using the -> operator followed by the return type.

func square(of number: Int) -> Int {
    return number * number
}

let result = square(of: 4)  // result is 16

We learnt about this syntax in 12DTC. However, in Python, it was not obligatory. Swift requires explicitly specifying the return type; this helps make the code safer and easier to reason about as both you, anybody who reads your code, and the Swift compiler can detect when the code in your function does not do what is expected.

  • Write a function cube(of:) that returns the cube of a given integer.
  • Call the function with different numbers and print the results.

Sometimes, a function may not always have a valid result. In such cases, use an [optional]() return type (?).

func divide(_ a: Int, by b: Int) -> Int? {
    if b == 0 {
        return nil  // Return nil when division by zero occurs
    }
    return a / b
}

if let result = divide(10, by: 2) {
    print("Result is \(result)")  // Prints: Result is 5
} else {
    print("Invalid division")
}

  • Modify the divide function above to return Double? instead of Int?.
  • Use optional binding (if let) to safely unwrap the result and print it.
  • Try calling the function with divide(10, by: 0) and handle the nil case.

Swift’s higher-order functions like map, filter, and reduce work well with named functions, provided the function signatures match their expected parameter and return types.

map applies a function to each element in an array to create a new array.

For example, the double function below expects a single Int; using map with the numbers list would also have a single Int (i.e. the number in numbers.map { number in ...); therefore, the double function can be supplied directly to the call to map.

func double(_ number: Int) -> Int {
    return number * 2
}

let numbers = [1, 2, 3, 4]
let doubledNumbers = numbers.map(double)
print(doubledNumbers)  // Output: [2, 4, 6, 8]

  • Write a function squareNumber(_:) that returns the square of a number.
  • Use it with map to square all numbers in an array.
  • Print the transformed array.

filter keeps elements that meet a condition:

func isEven(_ number: Int) -> Bool {
    return number % 2 == 0
}

let evenNumbers = numbers.filter(isEven)
print(evenNumbers)  // Output: [2, 4]

  • Write a function isPositive(_:) that returns true if a number is positive.
  • Use it with filter to remove negative numbers from an array.
  • Print the filtered array.

reduce is used to combine all elements into a single value:

func sum(_ total: Int, _ number: Int) -> Int {
    return total + number
}

let totalSum = numbers.reduce(0, sum)
print(totalSum)  // Output: 10

In the call to reduce, the first parameter remains the initial value; this is followed by the function.

  • Write a function multiply(_:_:) that multiplies two numbers.
  • Use reduce to find the product of all numbers in an array.
  • Print the final result.