Functions: Closures with a name

Syntax:
func processTaxes(income: Int) -> Int {
 let moneyOwed = income * 0.20
 return moneyOwed
}

A function is a named grouping of code that performs operations on a set of inputs. You can optionally provide default values for the inputs, or even declare them to be "in-out", which will modify the object passed in to the function rather than returning a new object. Every function has a type defined by the types of it's inputs and outputs. This allows Swift functions to be passed to other functions, or be returned from them. On the other hand, functions can also be declared with no input parameters and no return type.

// Basic function with one input and one output func stringSize(theString: String) -> Int {
  return theString.utf16Count
}

// Function with no parameters func heartbeatLog() {
  let timestamp = NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: .MediumStyle, timeStyle: .ShortStyle)
  println(@"@% and all is well", timestamp)
}

Functions can also return multiple values by using tuples. If the returned values are named in the function definition, they can be referred to with dot-notation by the calling code. If there might be a case where no values should be returned, you can use an optional tuple. Keep in mind that this is different from a tuple of optionals, where only some of the values might be missing.

// Basic function with one input and multiple outputs
func parseData(theData: String) -> (size: Int, comment: String) {
  let dataSize = countElements(theData)
  let dataComment = dataSize > 40 ? "long" : "short"
  return (dataSize, dataComment)
}

let myData = "This is not a very long string."
let result = parseData(myData)
println("The data of size \(result.size) is \(result.comment)")
// prints The data of size 31 is short


// Same function with optional tuple
func parseData(theData: String) -> (size: Int, comment: String)? {
  let dataSize = countElements(theData)
  if dataSize == 0 { return nil }
  let dataComment = dataSize > 40 ? "long" : "short"
  return (dataSize, dataComment)
}

let myData = "This is not a very long string."
if let result = parseData(myData) {
  println("The data of size \(result.size) is \(result.comment)")
}
/* also prints The data of size 31 is short, but notice the if-let syntax was required to unwrap the optional in this case.

If you need to modify a value passed in to your function, you can use the inout keyword. When doing so, only variables can be passed in to that parameter since the value might be changed. Also, to pass them in, you must prefix the argument with a & symbol.

func updateValue(inout word: String, num: Int) {
 if num == 5 { word = "Five" }
}
        
var someWord = "One"
let number = 5
updateValue(&someWord, number)
println("Word is now \(someWord)")
        
// prints Word is now Five