Functions

Functions are just Chunks of code, and we give a name so we can refer to them easily. Functions are designed to let us reuse code easily, which means we don’t have to copy and paste code to get common behaviors. so we can use it again and again. reuse it elsewhere. we can make a function, name it with parenthesis (). we have to put () at the end. Cos we ask Swift to run its code.

func showWelcome() {
    print("Welcome to my app!")
    print("By default this prints out a conversion")
}

showWelcome()

isMultiple(of: ) is also a function that belongs

let number = 139

if number.isMultiple(of: 2) {
    print("Even")
} else {
    print("Odd")
}

random() is a function too.

let roll = Int.random(in: 1...20)
print(roll)


so they are the function Apple have made. And we can make our own functions that are open to configuration, all by putting extra code in between the parentheses. we will place “number: Int” inside the parentheses. That’s called a “parameter”, and it’s our customize point.

func printTimesTables(number: Int) {
    for i in 1...5 {
        print("\(number) x \(i) is \(number * i)")
    }
}
printTimesTables(number: 3)

we can even make multiple parameters. For example, we can customize ho high our multiplication tables go, we might make the end of our range be set using a second parameter.

func printTimesTables2(number: Int, end: Int) {
    for i in 1...end {
        print("\(number) x \(i) is \(number * i)")
    }
}
printTimesTables2(number: 4, end: 2)



Return values from functions

Swift has lots of functions built in, a variety of mathematical functions such as “sqrt()” . The “sqrt()” function accepts one parameter, which is the number we want to calculate the “Square Root” of, and it will go ahead and do the work then send back the square root.

import SwiftUI

let root = sqrt(25)
print(root)

To return our own calue from a function, there are 2 steps.

  1. Write an arrow “->” and then write a data type.
  2. Use the “return” keyowrd to send back your data.


if we want to roll a dice in various parts of our program, we can make a function like this. Using this approach we can call “rollDice()” in lots of places across our program.

func rollDice() -> Int {
    return Int.random(in: 1...6)
}

let result = rollDice()
print(result)
print(result)

Now we’re gonna make a function to check if 2 strings contain the same letters. When a function has only one line of code, we can Remove the “return” keyword entirely.

func areLettersIdentical(string1: String, string2: String) -> Bool {
    string1.sorted() == string2.sorted()
}
print(areLettersIdentical(string1: "Joe", string2: "oeJ"))

Another example.

func sayHello(name: String) -> String {
    return "Hello, " + name
    
}
print(sayHello(name: "Joe"))


Let’s build a pythagoras() function that accepts two decimal numbers and returns another one. we have a triangle with one right angle inside, we can calculate the length of the hypotenuse by squaring both its other sides, adding them together, then calculating the square root of the result.

func pythagoras(a: Double, b: Double) -> Double {
    sqrt(a * a + b * b)
}
let c = pythagoras(a: 3, b: 4)
print(c)



Tuple

we can use a tuple type as the return type for a function to return 2 or More Values as part of one compound return value. Like arrays, dictionaries, and sets, Tuples let us put multiple pieces of data into a single variable. But Unlike those other options, Tuples can have a variety of data types and have a fixed size.

func getUser() -> (firstName: String, lastName: String) {
    (firstName: "Joseph", lastName: "Swift")
}

let user = getUser()
let firstName = user.firstName
let lastName = user.lastName

print("Name: \(firstName) \(lastName)")

Rather than assigning the tuple to constant ‘user’, Copying indicidual values out of there, We can shkip the 3 lines of code up there, We can make two separate constants from getUser().

let (firstName, lastName) = getUser()
print("Name: \(firstName) \(lastName)")

That syntax gives me headache, but it’s just shorthand for what we had before. Convert the tuple of two elements that we get back from getUser() into two separate constants.

if we don’t need all the values from the tuple we can go a step further by using “_” to tell Swift to ignore that part of the tuple.

let (firstName, _) = getUser()
print("Name: \(firstName)")



Customize Parameter Labels

if we came back to this code six months later, we feel confident this code will be pretty self-expanatory.

func rollDice(sides: Int, count: Int) -> [Int] {
    var rolls = [Int]()
    for _ in 1...count {
        let roll = Int.random(in: 1...sides)
        rolls.append(roll)
    }
    
    return rolls
}

let rolls = rollDice(sides: 6,count: 5)
print(rolls)

External and Internal Parameter names.

we can write a second name for parameter, one to use externally, and one to use internally.

func printTimesTables(for number: Int) {
    for i in 1...9 {
        print("\(number) x \(i) is \(i * number)")
    }
}

printTimesTables(for: 4)

The external name is “for”, the internal name is “number”, and it’s of type Int. When we call the func, we use the external name for the parameter. Becasue we are outside of the func. Inside the func, We have to use the internal name for the parameter.


Swift gives us two important ways to control parameter names: we can use “_” for the ecternal parameter name so that it doesn’tget used, or add a secon name there so that we have both external and internal parameter names.

func climbMountain(_ name: String) {
    print("I'm going to climb \(name). ")
}
climbMountain("Everest")