Functions 101 in swift

Functions are the building blocks of any application. Let's start with some obvious characteristics about them. The functions declared using the keyword func. Then follows the function name and the parenthesis containing the parameters, after that there is an arrow "->" and the return type is defined. So, it looks like:

func myFunction(myParameter: type) -> myReturnType {
  // The code of the function
}

Inside the function, we have direct access to the input parameters and at the end we should use return to return the result, like:

func rectangleArea(side: Int) -> Int {
  return side*side
}

and we call this by:

rectangle(10)

In case that you have more than one parameters you can add them inside the parenthesis. At this point and for the second parameter and on we can use external names for the parameters to make the function more readable (for the first argument the name is included in the function name). So lets say that we want a function to calculate the volume of a cylinder.

import Darwin // to get access to M_PI
func cylinderVolumeWithRadius(radius: Double, andHeight height: Double) -> Double {
    return M_PI * pow(radius, 2) * height
}

cylinderVolumeWithRadius(10, andHeight: 10)

In the function's implementation code we use the internal parameters' names and in order to call it we use the external. If for some reason we don't want any external parameters and we prefer only to give the input values, comma separated, the "_" comes for the rescue.

So, we define the function like:

func cylinderVolumeWithRadius(radius: Double, _ height: Double) -> Double {
    return M_PI * pow(radius, 2) * height
}

and we call it:

cylinderVolumeWithRadius(10, 10)

If you though that without using external name you will achieve the same result you were wrong. In that case the internal name from the second parameter and on is used for both the internal and the external name. So it will be,

func cylinderVolumeWithRadius(radius: Double, height: Double) -> Double {
    return M_PI * pow(radius, 2) * height
}

and we call it:

cylinderVolumeWithRadius(10, height: 10)

Enough with the parameter list... No not yet!

Say that we want to write a function that adds an exclamation mark in the input string to express how excited we are learning Swift.

Let's see it simple as that:

var name = "Angelos"

func getExcitedWith(name: String) {
  name += String("!")
  print(name)
}

Is it work? No... It is not complied at all. Why?
Because the parameter list is comprised of constants. In order to be able to change the values we need to add var in front of the argument. So it will become:

var name = "Angelos"

func getExcitedWith(var name: String) {
  name += String("!")
  print(name)
}

getExcitedWith(name)
print(name)

Let's take a look at the debug output.
Angelos!
Angelos

Hmm, the function makes a copy of the variable name, so when it returns the initial value remains untouched. This is a desirable characteristic cause we don't like functions to mess up with our variables. In case that we want to allow the function to change our app's variables there is a way.

We can use the inout keyword like:

var name = "Angelos"

func getExcitedWith(inout name: String){
    name += String("!")
    print(name)
}

getExcitedWith(&name)
print(name)

In that case the output is:
Angelos!
Angelos!

What happened? Well, in this point we use pass by reference and rather than giving a copy of the variable in the function to work with, we pass the address of the variable. This is why in function call we use the & to apps the address.

Are you ready for something more advanced?

What if I told that you can use a parameter list with a variable number of arguments (of the same type)?

Yes, it is possible using the variadic parameter ... which accepts zero or more values. So if we need to calculate the mean value of some numbers without knowing how many they are, we can write a function like:

func meanValueOf(numbers: Double...) -> Double {

  var sum: Double = 0.0

  for num in numbers {
      sum += num
  }

  return sum / Double(numbers.count)
}

Yes exactly, numbers become an array of the input arguments and it can be handled like that.

Enough, with the input arguments? What about the return value?

We said that the return type is defined after the arrow and as we know from other languages is one value, connect?

No, in swift we can return more than one value using tuples! Lets see an example. Lets say that we define a cube and we want to calculate the volume and the area of one face.

func cubeAnalysisWithSide(side: Double) -> (area: Double, volume: Double) {
  return (pow(side, 2), pow(side, 3))
}

let myCube = cubeAnalysisWithSide(10)
let faceArea = myCube.area
let cubeVolume = myCube.volume

Amazing?

OK, if you want the playground with the code you can find here.

Keep on playing!

Leave a Reply

Your email address will not be published. Required fields are marked *